Updated: 01-06-2003; 19:12:45.
Nielsen's Weblog
.NET [use your Context dude]
        

17. maj 2003

TSS is all hyped up about Cameron's  performance test JVM vs CLR (wow big headlines all for nothing).

On the surface it looks like java it a winner here, so with the risk of getting flamed here, I say the performance test sux and it sux big time. this is what happens if you play with things you don't understand.

the code looks pretty simply, but what Cameron didn't cared about was Boxing and Capacity. Ignoring boxing/unboxing, can slow your program down. period. Beauty and the beast in the CLR.

value types, such as int's requires boxing in order to be treated as objects, so looking at his code

list.Add(new Person(i, "John " + i));

take a look at the IL code :

IL_0011:  ldstr      "John "
IL_0016:  ldloc.1
IL_0017:  box        [mscorlib]System.Int32  <-- boxing takes place here
IL_001c:  call       string [mscorlib]System.String::Concat(object,  <--
                                                                                       object)  <--
IL_0021:  newobj     instance void people.Person::.ctor(int32,
                                                                                     string)
IL_0026:  callvirt   instance int32 [mscorlib]System.Collections.ArrayList::Add(object)

no boxing occurs here:

list.Add(new Person(i, "John " + i.ToString()));

IL code:

IL_001c:  ldstr      "John "
IL_0021:  ldloca.s   V_1
IL_0023:  call       instance string [mscorlib]System.Int32::ToString()
IL_0028:  call       string [mscorlib]System.String::Concat(string,
                                                                                       string)
IL_002d:  newobj     instance void people.Person::.ctor(int32,
                                                                                    string)
IL_0032:  callvirt   instance int32 [mscorlib]System.Collections.ArrayList::Add(object)

also notice the String::Concat here.

another optimization is calling the ArrayList.Capacity, this will reallocated the internal array, thereby preventing this from happening during the loop.

also in his 'test' method which gets called in a loop:

DateTime finish = DateTime.Now;
Console.WriteLine("Total time for iteration " + iIter + ": " + (finish - start));

IL code:
IL_004d:  box        [mscorlib]System.TimeSpan <--- boxing.
IL_0052:  stelem.ref
IL_0053:  ldloc.3
IL_0054:  call       string [mscorlib]System.String::Concat(object[]) <--
IL_0059:  call       void [mscorlib]System.Console::WriteLine(string)
IL_005e:  ret
} // end of method ManyPeople::test
actually boxing takes place with iIter value type also. IL code not shown, I assume you believe me.

a simple rewrite and no boxing takes place:

DateTime finish = DateTime.Now;
TimeSpan dt = finish - start;
Console.WriteLine("Total time for iteration " + iIter.ToString() + ": " + dt.ToString());

so here are my results, funny it shows a different picture, yeah go figure :-)

ladies first:

C:perfjavaperfclasses>java ManyPeople
Total time for iteration 0: 5417
Total time for iteration 1: 5298
Total time for iteration 2: 5298
Total time for iteration 3: 5297
Total time for iteration 4: 5288
Total time for iteration 5: 5297
Total time for iteration 6: 5298


C:perfjavaperfclasses>java -server -Xms24m -Xmx24m ManyPeople
Total time for iteration 0: 4467
Total time for iteration 1: 4316
Total time for iteration 2: 4306
Total time for iteration 3: 4326
Total time for iteration 4: 4307
Total time for iteration 5: 4326
Total time for iteration 6: 4316

C:perfjavaperfclasses>java -server -Xms128m -Xmx128m ManyPeople
Total time for iteration 0: 3616
Total time for iteration 1: 3364
Total time for iteration 2: 3445
Total time for iteration 3: 3405
Total time for iteration 4: 3445
Total time for iteration 5: 3445
Total time for iteration 6: 3345

ok the hotspot does a better job from time to time.

and now for the C# version with no boxing and use of Capacity.

C:perfpeoplepeoplebinRelease>people
Total time for iteration 0: 00:00:03.1945936
Total time for iteration 1: 00:00:02.9542480
Total time for iteration 2: 00:00:03.0844352
Total time for iteration 3: 00:00:03.1244928
Total time for iteration 4: 00:00:03.1545360
Total time for iteration 5: 00:00:03.0443776
Total time for iteration 6: 00:00:02.7840032

hmm close race, but far from Cameron's results.

actually I tried to ngen.exe on my code, is showed this:


C:perfpeoplepeoplebinRelease>people
Total time for iteration 0: 00:00:03.1044640
Total time for iteration 1: 00:00:02.9141904
Total time for iteration 2: 00:00:03.1845792
Total time for iteration 3: 00:00:03.4048960
Total time for iteration 4: 00:00:03.1244928
Total time for iteration 5: 00:00:03.3748528
Total time for iteration 6: 00:00:03.1244928

but if you rewrite his 'Average' method

Person[] p = new Person[100000];
for (Int32 i = 0; i < 100000; i++)
 p[i] = new Person(i, "John " + i.ToString()); //no boxing now

long silly = 0;

for (Int32 x = 0; x < p.Length; x++) //get rid of the slow foreach
 silly += p[x].Id;

return silly / 100000;

it shows this result with ngen.exe

C:perfpeoplepeoplebinRelease>people
Total time for iteration 0: 00:00:02.9342192
Total time for iteration 1: 00:00:03.0443776
Total time for iteration 2: 00:00:02.8941616
Total time for iteration 3: 00:00:02.8841472
Total time for iteration 4: 00:00:02.9842912
Total time for iteration 5: 00:00:02.9942912
Total time for iteration 6: 00:00:02.8841472

not spectacular faster. The CLR makes some pretty smart choices when loading and jit'ing the code.

now with boxing and no Capacity, it looks like this

C:perfpeoplepeoplebinRelease>people
Total time for iteration 0: 00:00:04.3662784
Total time for iteration 1: 00:00:04.1259328
Total time for iteration 2: 00:00:04.6166384
Total time for iteration 3: 00:00:04.3863072
Total time for iteration 4: 00:00:04.1059040
Total time for iteration 5: 00:00:04.1459616
Total time for iteration 6: 00:00:04.0958896

you see the performance loss here. yeah baby.

how many times have TSS published crappy performance test so far ? way to many times imo.

funny thing happened I accidentally tried to compile the java code with vs.net until I saw it was the java code I was trying to compile...yeah the code does look awful lot alike, let's just sit down in a circle and smoke.

test was made on a 2,4 ghz notebook, running XP proff. 512 ram, using vs.net 2003 ver 1.1 and jdk 1.4.1_02.

peace man.

 


12:17:37 AM    comment []

© Copyright 2003 Allan Nielsen.
 
May 2003
Sun Mon Tue Wed Thu Fri Sat
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Apr   Jun


Click here to visit the Radio UserLand website.

Subscribe to "Nielsen's Weblog" in Radio UserLand.

Click to see the XML version of this web page.

Click here to send an email to the editor of this weblog.