Check if values are those same objects - flutter

I'm pretty new to Dart and I got some problems with understanding what is going on under the hood. I've simple code like this:
void main() {
String s1 = "test1";
StringBuffer sb = StringBuffer();
sb.write("test");
sb.write("1");
String s2 = sb.toString();
print(identical(s1, s2));
print(s1 == s2);
int a = 1;
int b = 1;
print(identical(a, b));
}
result of this code is 3x true
Which is little tricky for me. As I understands all variables refers to some values, and since == operator is expected to return true, I'm little confused why identical also return true. If I would use code like:
String s1 = "test1";
String s2 = "test1";
Then I would expect that there is compiler optimization for immutable strings. But since I combine it via StringBuffer I would expect that I got two different values in memory. I suspect that identical uses == operator internally... Why I'm curious: I'm working on app which will use sets of tags. And I'm not sure If should I create some pool of strings and checks if some strings are already created and reuse it or just spawn strings and Dart has it's own string pool?

Related

how can this Repeated string concatenation function

using UnityEngine;
using System.Collections;
public class NewMonoBehaviour1 : MonoBehaviour
{
void ConcatExample(int[] intArray)
{
string line = intArray[0].ToString(); // the line is the var of the first in array
for(i =1;i <intArray.Length; i++) // the length is unknown ?
{
line += ", " + intArray[i].ToString(); //
}
return line;
//each time allocate new in original place
}
}
How can this function work ? the length of array is unknown , so how the for loop works ?Besides, this is void function but shouldn't return anythings right ,or is there any exceptional case ,finally,according to the unity manual, it is said that the function will keep producing a string but with new contents in the same place , resulting in consuming large memory space .Why ?thx
What makes you think that the Length should be unknown? It is a property that any array simply has
Gets the total number of elements in all the dimensions of the Array.
Of course it is not unknown the moment you call your method with an according parameter!
The return line; will not even compile since as you say the method is of type void so it can not return anything. It should probably be private string ConcatExample
Then what the unity manual (don't know where exactly you read this) means lies in
line += ", " + intArray[i].ToString();
under the hood every string in c# is an immutable char[]. So everytime you do a string concatenation via stringC = stringA + stringB what happens under the hood is basically something similar to
char[] stringC = new char[stringA.Length + stringB.Length];
for(var iA = 0; iA < stringA.Length; iA++)
{
stringC[i] = stringA[i];
}
for(var iB = 0; iB < stringB.Length; iB++)
{
stringC[iB + stringA.Length] = stringB[iB];
}
so whenever dealing with loops especially with large data it is strongly recommended to rather use a StringBuilder like
private string ConcatExample(int[] intArray)
{
var builder = new StringBuilder(intArray[0]);
for(i =1; i < intArray.Length; i++)
{
builder.Append(", ").Append(intArray[i].ToString());
}
return builder.ToString();
}
The length of the array will be the length of the array of ints you pass into the function as an argument.
say you pass it
Int[] ints = {1,2,3}
ConcatExample(ints); //the length of the array is now 3
add a debug.log() function to the ConcatExample method
void ConcatExample(int[] intArray)
{
string line = intArray[0].ToString();
for (int i = 1; i < intArray.Length; i++)
{
line += ", " + intArray[i].ToString(); //
Debug.Log(line);
}
}
debug.log would produce the following in the console
1, 2
1, 2, 3
and finally the return line; at the end would just result in an error because yes you are correct void returns nothing
This function CANNOT work, unless it gets the data it expects. A NULL passed to this function, for example, would generate a runtime null-reference exception. Passing a valid integer array, of length zero would generate an invalid index error on the first line.
You are correct, the function returns nothing, and appears pointless. In fact, I would have expected return line; to generate a complier error.
The string type appears "dynamic" meaning, it will indeed allocate more and more memory as needed. Technically, it is actually the string "+" operator, (a function that takes two strings as parameters) that is allocating this space. This function returns a new string, of the appropriate size. The garbage collector will DEallocate "old" strings when they are no longer referenced by any variables.

Support for basic datatypes in H5Attributes?

I am trying out the beta hdf5 toolkit of ilnumerics.
Currently I see H5Attributes support only ilnumerics arrays. Is there any plan to extend it for basic datatypes (such as string) as part of the final release?
Does ilnumerics H5 wrappers provide provision for extending any functionality to a particular
datatype?
ILNumerics internally uses the official HDF5 libraries from the HDF Group, of course. H5Attributes in HDF5 correspond to datasets with the limitation of being not capable of partial I/O. Besides that, H5Attributes are plain arrays! Support for basic (scalar) element types is given by assuming the array stored to be scalar.
Strings are a complete different story: strings in general are variable length datatypes. In terms of HDF5 strings are arrays of element type Char. The number of characters in the string determines the length of the array. In order to store a string into a dataset or attribute, you will have to store its individual characters as elements of the array. In ILNumerics, you can convert your string into ILArrray or ILArray (for ASCII data) and store that into the dataset/ attribute.
Please consult the following test case which stores a string as value into an attribute and reads the content back into a string.
Disclaimer: This is part of our internal test suite. You will not be able to compile the example directly, since it depends on the existence of several functions which may are not available. However, you will be able to understand how to store strings into datasets and attributes:
public void StringASCIAttribute() {
string file = "deleteA0001.h5";
string val = "This is a long string to be stored into an attribute.\r\n";
// transfer string into ILArray<Char>
ILArray<Char> A = ILMath.array<Char>(' ', 1, val.Length);
for (int i = 0; i < val.Length; i++) {
A.SetValue(val[i], 0, i);
}
// store the string as attribute of a group
using (var f = new H5File(file)) {
f.Add(new H5Group("grp1") {
Attributes = {
{ "title", A }
}
});
}
// check by reading back
// read back
using (var f = new H5File(file)) {
// must exist in the file
Assert.IsTrue(f.Get<H5Group>("grp1").Attributes.ContainsKey("title"));
// check size
var attr = f.Get<H5Group>("grp1").Attributes["title"];
Assert.IsTrue(attr.Size == ILMath.size(1, val.Length));
// read back
ILArray<Char> titleChar = attr.Get<Char>();
ILArray<byte> titleByte = attr.Get<byte>();
// compare byte values (sum)
int origsum = 0;
foreach (var c in val) origsum += (Byte)c;
Assert.IsTrue(ILMath.sumall(ILMath.toint32(titleByte)) == origsum);
StringBuilder title = new StringBuilder(attr.Size[1]);
for (int i = 0; i < titleChar.Length; i++) {
title.Append(titleChar.GetValue(i));
}
Assert.IsTrue(title.ToString() == val);
}
}
This stores arbitrary strings as 'Char-array' into HDF5 attributes and would work just the same for H5Dataset.
As an alternative solution you may use HDF5DotNet (http://hdf5.net/default.aspx) wrapper to write attributes as strings:
H5.open()
Uri destination = new Uri(#"C:\yourFileLocation\FileName.h5");
//Create an HDF5 file
H5FileId fileId = H5F.create(destination.LocalPath, H5F.CreateMode.ACC_TRUNC);
//Add a group to the file
H5GroupId groupId = H5G.create(fileId, "groupName");
string myString = "String attribute";
byte[] attrData = Encoding.ASCII.GetBytes(myString);
//Create an attribute of type STRING attached to the group
H5AttributeId attrId = H5A.create(groupId, "attributeName", H5T.create(H5T.CreateClass.STRING, attrData.Length),
H5S.create(H5S.H5SClass.SCALAR));
//Write the string into the attribute
H5A.write(attributeId, H5T.create(H5T.CreateClass.STRING, attrData.Length), new H5Array<byte>(attrData));
H5A.close(attributeId);
H5G.close(groupId);
H5F.close(fileId);
H5.close();

What is the alternative for String.format() in GWT?

While GWT is not emulate all java's core, what can be used as alternative for:
String.format("The answer is - %d", 42)?
What is the ellegant and efficient pattern to inject arguments to message in GWT?
One elegant solution is using SafeHtml templates. You can define multiple such templates in an interface like:
public interface MyTemplates extends SafeHtmlTemplates {
#Template("The answer is - {0}")
SafeHtml answer(int value);
#Template("...")
...
}
And then use them:
public static final MyTemplates TEMPLATES = GWT.create(MyTemplates.class);
...
Label label = new Label(TEMPLATES.answer(42));
While this is a little bit more work to set up, it has the enormous advantage that arguments are automatically HTML-escaped. For more info, see https://developers.google.com/web-toolkit/doc/latest/DevGuideSecuritySafeHtml
If you want to go one step further, and internationalize your messages, then see also https://developers.google.com/web-toolkit/doc/latest/DevGuideI18nMessages#SafeHtmlMessages
You can simply write your own format function instead of doing brain storm.
public static String format(final String format, final String... args,String delimiter) {
String[] split = format.split(delimiter);//in your case "%d" as delimeter
final StringBuffer buffer= new StringBuffer();
for (int i= 0; i< split.length - 1; i+= 1) {
buffer.append(split[i]);
buffer.append(args[i]);
}
buffer.append(split[split.length - 1]);
return buffer.toString();
}
Because most (as in 99.999%) message formats are static, known at compile-time, the way GWT approaches it is to parse them at compile-time.
You'll generally use a Messages subinterface for its ability to localize the message, but you'll sometimes rather need SafeHtmlTemplates.
In the 0.001% when template is not known at compile time you can use Javascript sprintf (see: http://www.diveintojavascript.com/projects/javascript-sprintf) as in:
public static native String format (String format, JsArrayMixed values) /*-{
return vsprintf(format, values);
}-*/;
You can write your own.
I wrote a version that just work with Strings(%s):
public static String format(final String format, final Object... args)
{
checkNotNull(format);
checkNotNull(args);
final String pattern = "%s";
int start = 0, last = 0, argsIndex = 0;
final StringBuilder result = new StringBuilder();
while ((start = format.indexOf(pattern, last)) != -1)
{
if (args.length <= argsIndex)
{
throw new IllegalArgumentException("There is more replace patterns than arguments!");
}
result.append(format.substring(last, start));
result.append(args[argsIndex++]);
last = start + pattern.length();
}
if (args.length > argsIndex)
{
throw new IllegalArgumentException("There is more arguments than replace patterns!");
}
result.append(format.substring(last));
return result.toString();
}
why not writing a method like:
String appendAnswer(int result) {
return "The answer is - " + Integer.toString(result);
}
is resolving your problem because you do nothing like formatting in your code.
if you ever face the problem like converting integer/byte to Hex String you should use:
Integer.toString(int, 16);
I don't know GWT much but I am working on a GWT project and I needed this. While trying some alternatives, I have found that this is working;
import java.text.MessageFormat;
MessageFormat.format("The answer is - {0}", 42);
I don't know if the project's developers added something special to make this work or it is working by default.

IronRuby performance issue while using Variables

Here is code of very simple expression evaluator using IronRuby
public class BasicRubyExpressionEvaluator
{
ScriptEngine engine;
ScriptScope scope;
public Exception LastException
{
get; set;
}
private static readonly Dictionary<string, ScriptSource> parserCache = new Dictionary<string, ScriptSource>();
public BasicRubyExpressionEvaluator()
{
engine = Ruby.CreateEngine();
scope = engine.CreateScope();
}
public object Evaluate(string expression, DataRow context)
{
ScriptSource source;
parserCache.TryGetValue(expression, out source);
if (source == null)
{
source = engine.CreateScriptSourceFromString(expression, SourceCodeKind.SingleStatement);
parserCache.Add(expression, source);
}
var result = source.Execute(scope);
return result;
}
public void SetVariable(string variableName, object value)
{
scope.SetVariable(variableName, value);
}
}
and here is problem.
var evaluator = new BasicRubyExpressionEvaluator();
evaluator.SetVariable("a", 10);
evaluator.SetVariable("b", 1 );
evaluator.Evaluate("a+b+2", null);
vs
var evaluator = new BasicRubyExpressionEvaluator();
evaluator.Evaluate("10+1+2", null);
First Is 25 times slower than second. Any suggestions? String.Replace is not a solution for me.
I do not think the performance you are seeing is due to variable setting; the first execution of IronRuby in a program is always going to be slower than the second, regardless of what you're doing, since most of the compiler isn't loaded in until code is actually run (for startup performance reasons). Please try that example again, maybe running each version of your code in a loop, and you'll see the performance is roughly equivalent; the variable-version does have some overhead of method-dispatch to get the variables, but that should be negligible if you run it enough.
Also, in your hosting code, how come you are holding onto ScriptScopes in a dictionary? I would hold onto CompiledCode (result of engine.CreateScriptSourceFromString(...).Compile()) instead -- as that will help a lot more in repeat runs.
you can of course first build the string something like
evaluator.Evaluate(string.format("a={0}; b={1}; a + b + 2", 10, 1))
Or you can make it a method
if instead of your script you return a method then you should be able to use it like a regular C# Func object.
var script = #"
def self.addition(a, b)
a + b + 2
end
"
engine.ExecuteScript(script);
var = func = scope.GetVariable<Func<object,object,object>>("addition");
func(10,1)
This is probably not a working snippet but it shows the general idea.

Writing NUnit test code

How can I write code for the below method so that it can be tested in NUnit? How to handle a Hashtable?
public DataSet MySampleMethod(int param1, string param2, Hashtable ht)
{
if(ht==null)
{
ht = new Hashtable();
}
ht.Add("testKey","testData");
DataSet ds = new DataSet();
ds.Tables.Add();
ds.Tables[0].Columns.Add("Column1");
ds.Tables[0].Columns.Add("Column2");
ds.Tables[0].Columns.Add("Column3");
DataRow dr = ds.Tables[0].NewRow();
dr["Column1"] = "My column 1";
dr["Column2"] = "My column 2";
dr["Column3"] = "My column 3";
ds.Tables[0].Rows.Add(dr);
DataRow dr1 = ds.Tables[0].NewRow();
dr1["Column1"] = param1.ToString();
dr1["Column2"] = param2;
dr1["Column3"] = ht["testKey"].ToString();
ds.Tables[0].Rows.Add(dr1);
return ds;
}
First question to ask is: Why do I need to write this method? What's it doing for me?
Give the method a more human-friendly name.
From what I can see, the method takes in an integer, a string and a hashtable. The method is then expected to return a dataset containing a solitary table with 3 columns,
the first row contains values like {"My Column {ColumnNo}"..}
the second row of which contains the [ intParam.ToString(), stringParam, hashtable["testKey"] ]
Testing this method should be trivial,
Test#1:
Arrange : Create known inputs (an int I , string S, a hashtable with some "testData"=> Y)
Act : Call the method and obtain the resulting dataset
Assert : Query the dataset to see if it has the single table with 2 records. Inspect the contents of the records of the table to see if they contain the header row and the row with [I, S, Y].
Test#2:
Similar to above test, except that you pass in null for the hashtable parameter.
That's all I could see based on the snippet you posted.
HTH
Update: Not sure what you mean here by "handle hashtable" or "write test fixture code for hashtable" ? The hashtable is just a parameter to your function.. so I reckon the test would look something like this (Forgive the bad naming and lack of constants... can't name them unless I know what this function is used for in real life)
[Test]
public void Test_NeedsABetterName()
{
int intVal = 101; string stringVal = "MyString"; string expectedHashValue = "expectedValue";
Hashtable ht = new Hashtable();
ht.Add("testKey", expectedHashValue);
Dataset ds = MySampleMethod(intVal, stringVal, ht);
Assert.AreEqual(1, ds.Tables.Count);
Assert.AreEqual(2, ds.Tables[0].Rows.Count);
// check header Row1.. similar to Row2 as shown below
DataRow row2 = ds.Tables[0].Rows[1];
Assert.AreEqual(intVal.ToString(), row2["Column1"]);
Assert.AreEqual(stringVal, row2["Column2"]);
Assert.AreEqual(expectedHashValue, row2["Column3"])
}
I'd recommend getting a good book like Pragmatic Unit Testing in C# with NUnit or one from the list here to speed you up here.