[Frissítve] Furcsa Internet Explorer 9 teszteredmények a SunSpider benchmarkban

Napjaink elterjedt böngészői JavaScript teljesítményének mérésére gyakran használják az Apple WebKit csapata által létrehozott SunSpider benchmarkot. Mivel a böngészőgyártók újabban előszeretettel hivatkoznak termékeik JavaScript teljesítményére, egyáltalán nem mindegy, hogy melyik böngésző hogyan teljesít az ilyen benchmarkokban.

Frissítés: A Microsoft IE csapat blogjában adott magyarázatot a jelenségre, ami szerintük a "dead code elimination" használatából adódik. A részletek - az IE9 Preview 6 bejelentésével egyetemben - itt.

A Mozilla egyik mérnöke, Rob Sayre nemrég bejelentést tett a Microsoft-nál arra panaszkodva, hogy az IE 9 fura értékeket produkál a SunSpider math-cordic tesztjében. Az IE9 ebben a tesztben túl gyors. Valójában 10-szer gyorsabb a többi böngészőnél.

Sayre, hogy megfejtse az okát annak, hogy az IE9 miért ilyen gyors ebben a tesztben, egy kicsit módosította a SunSpider kódját. Egyszer beletett egy true;-t, egyszer pedig egy return;-t.

Elvileg ennek nem nagyon kellett volna befolyásolnia a benchmarkot, de mégis az lett az eredménye, hogy az IE9-ben 20-szor annyi idő alatt futottak le a tesztek, mint a változtatások nélkül.

A blogbejegyzés kapcsán megindultak a találgatások. Ezek közt van olyan, amely szerint az IE9 csal a SunSpider-ben, a Microsoft a SunSpider-re optimalizálta az IE9-et, van aki szerint az IE9 egyszerűen csak jól végzi a dolgát és megfelelően optimalizál. Hivatalos magyarázat még nem érkezett a Microsoft-tól.

Linkek:
Reporting a bug on a fragile analysis
Internet Explorer 9 Caught Cheating In SunSpider Benchmark?

Hozzászólások

Az ISA buszos korszakban az első VGA felbontású kártyák megjelenése után nem sokkal volt egy cég amelyiknek a kártyája föltűnően jól szerepelt egy teszten. A tesztben volt egy angol mondat amiben minden (angol) betű megtalálható. A barna róka átugorja a lusta kutyát? Valami ilyesmi. A lényeg hogy valakinek gyanús lett a jó szereplés és megnézte a kártya BIOS-át. Rátalált benne az említett mondatra. Kiderült hogy a BIOS figyeli ezt a mondatot és ha ezt akarják kiíratni a képernyőre akkor felgyorsítja a műveletet. Skandalum lett belőle és az illető cég gyorsan "kijavította a hibát". A jobb emlékezetűek talán pontosítani tudják a történetet.

epic fail :)

kb mint anno az AMD k6-okban a benchmark loop-ok kioptimalizalasa, elore beegetett fix branch decision tablakkal

A'rpi

Asszem feladtak a lecket az MS PR csapatanak. Kivancsi leszek, hogy megprobaljak-e kimagyarazni, vagy inkabb lapitanak.

--
The iPad: Because the iPhone was too small for other people to notice you.

van aki szerint az IE9 egyszerűen csak jól végzi a dolgát és megfelelően optimalizál

Ki az a hülye, aki szerint a megfelelő (persze általános) optimalizáció egy return miatt 20-adjára esik vissza?
Azt pedig ne mondják nekem, hogy az optimalizáció, amikor egy felismert kódra beépített eredményt ad vissza...

---
BME-VIK '09
Compaq Mini 311 - N270 @ 2323 MHz - 3GB DDR3 @ 1240 MHz - ION

Ezt hívják cache-nek, de akkor az első teszt alkalmával is ugyan olyan lassúnak kellett volna lennie, mint az átírás után.
Szóval, akkor valahogy így nézne ki a dolog:
1. Futás: lassú
2. Futás: gyors
3. Átírt kód 1. futás: lassú
4. Átírt kód 2. futás: gyors
---
BME-VIK '09
Compaq Mini 311 - N270 @ 2323 MHz - 3GB DDR3 @ 1240 MHz - ION

http://news.ycombinator.com/item?id=1913368

Kicsit szakmaibb diskurzus a temaban, nem tudni, hogy pontosan mit csinal az IE 9, de elegge erdekes. Valoszinu, hogy valamifele dead code optimization, de nem nagyon sikerult masfele -- ilyen szempontbol hasonlo -- kodokon reprodukalni.

Egyébként tetszik a hozzáállásuk. Annak ellenére, hogy vezetik a tesztet feleslegesnek tartják.

We’ve been consistent in our point of view that these tests are at best not very useful, and at worst misleading. Even with the most recent results in the chart above, our motivations and our point of view remain unchanged. We’ve focused on improving real world site performance. We’ve made progress on some microbenchmarks as a side effect. Focusing on another subsystem microbenchmark is not very useful.

http://blogs.msdn.com/b/ie/archive/2010/11/17/html5-and-real-world-site…
Dead Code Elimination in JavaScript
One of the changes we made to the IE9 JavaScript Engine, codenamed Chakra, to improve performance on real world web sites involves dead code elimination. Yesterday afternoon, someone posted a question (“What sorts of code does the analysis work on, other than the exact [math-cordic test] function included in SunSpider,”) on the Microsoft Connect feedback site. Given some recent interest in this question, this blog answers that question.

Briefly, the IE9 JavaScript engine includes many different changes to improve the performance of real-world Web sites and applications. You can see this in action by visiting www.ietestdrive.com and trying the samples there with IE9 and other browsers. The behavior of the IE9 JavaScript engine is not a “special case optimization” for any benchmark and not a bug.

Some of the optimizations we’ve made to the JavaScript interpreter/compiler in IE9 are of a type known in the compiler world as dead code elimination. Dead code elimination optimizations look for code that has no effect on a running program, and removes the code from the program. This has a benefit of both reducing the size of the compiled program in memory and running the program faster.

Here is a very simple example of JavaScript code that is a candidate for dead code elimination. Because the conditional will always evaluate to false, the JavaScript engine can eliminate this code altogether.

function func() {
var x = 1;
var y = 3;
var w = x + y;

if (w != 4) {
// dead code
}
}Dead code elimination is especially effective when code would be executed many times, as in a loop. In the following example, the code in the loop repeatedly overwrites the same variable (what is known in computer science as a dead store), so it can be reduced to only one call.

function func(a, b) {
var x;
var i = 300;
while (i--) {
x = a + b; // dead store
}
}In the example below, the code executed in the loop is not used anywhere in the program outside the loop, so the entire loop can be safely removed.

function sum() {
var a = [1, 2, 3, 4, 5];
var sum = 0.0;

// dead loop elimination
for (var i = 0; i < 5; i++) {
sum += a[i];
}
}Developers often write dead code without knowing it and can rely on compilers to optimize the code. Most modern compilers today run an extensive set of dead code elimination optimizations.

So, why does this affect the math-cordic benchmark in the Webkit SunSpider suite? Let’s take a look at the inner function in the test.

function cordicsincos() {
var X;
var Y;
var TargetAngle;
var CurrAngle;
var Step;
X = FIXED(AG_CONST); /* AG_CONST * cos(0) */
Y = 0; /* AG_CONST * sin(0) */

TargetAngle = FIXED(28.027);
CurrAngle = 0;
for (Step = 0; Step < 12; Step++) {
var NewX;
if (TargetAngle > CurrAngle) {
NewX = X - (Y >> Step);
Y = (X >> Step) + Y;
X = NewX;
CurrAngle += Angles[Step];
} else {
NewX = X + (Y >> Step);
Y = -(X >> Step) + Y;
X = NewX;
CurrAngle -= Angles[Step];
}
}
} The benchmark runs an expensive loop, and then does nothing with the results; the benchmark is written exactly in a way that triggers this general optimization.

Of course, the benchmark could be rewritten to avoid triggering this optimization, which would bring our performance on this specific benchmark in line with other browsers.

The interest in this issue is a great example of why these microbenchmarks fail to represent the real world web. Webkit Sunspider uses an expensive JavaScript loop to approximate sine and cosine. Real world sites would actually use the much faster and CPU-optimized functions already available in JavaScript engines.

These optimizations are relatively new to the world of JavaScript runtimes even though there are many examples of dead code in real-world JavaScript on the Web. These optimizations often require significant flow analysis of the code, and in a real world site, spending too much time analyzing code can reduce the responsiveness of the page. The Chakra engine picks the right balance between code quality and analysis time, and only performs a small set of dead code optimizations. We continue to tune this for IE9, and bugs reported via Microsoft Connect are examples of where the optimization could do more. We continue to tune these and other optimizations for the final release.

This kind of dead code elimination is one of many optimizations that Chakra makes to reduce unnecessary work. Over the next few days we’ll post about some of the other techniques Chakra uses to deliver great performance.

A JITeket az vajmi kevesse zavarja, a nem hasznalt fuggvenyeket eleve nem fogja forditani. Itt hasznalt fuggvenyen beluli elagazasokrol beszelunk.

Mondjuk a jQuery a maga kb 1600 soraval sok vizet nem zavar, de egy ext js a tomoritett 600KB-val (ebben kepek nincsenek!) mar valoszinuleg viccesebb.

Nem all szandekomban allast foglalni arrol, hogy az ie/Sunspider jo-e, van-e relevanciaja, stb. Sot, a JS-hez, JS engine-ekhez sem ertek, viszont a temaban "laikuskent" sem tudom egyelore elfogadni ezt a valaszt.

Ha jol ertem, a magyarazat az, hogy a dead-code-elimination nincs meg jol tuningolva. Lehet nekem van csak koran, de nem ertem hogyan. Ket lehetoseget latok, ami megmagyarazhatna a jelenseget:
1) csak a +return esetben lett ez a dolog triggerelve, es ez vette el az idot
2) mindket esetben triggerelve lett, de masodik esetben nem tudta leegyszerusiteni a fuggvenyt

A dead-code-elimination-nek a mai vilagban valoszinuleg megvan a relevanciaja, de ettol fuggetlenul nem ertem, hogy egy +return hogy okozhatta az 1-es vagy 2-es eset valamelyiket. Ha valaki ezt kifejtene bovebben, akkor azt megkoszonnem. (A hivatkozott oldalt most csak vegigfutottam, commenteket nem neztem meg, amennyiben ott van a valasz, akkor elnezest kerek, egy rtf-fel kezdodo szo is boven eleg, koszonom)

Nem, ha van egy ilyen függvényed, hogy

function x() {
var x = 0;
for (var i = 0;i<100000;i++) {
x += i;
}
}

akkor a ciklus, és így az egész függvény "dead code", mert hogy az x-et nem használja semmire, azaz ki lehet hagyni. Ha berakunk egy "return x"-et a végére, akkor viszont már nem lesz dead code, és hirtelen sokkal lassabb lesz az egész

De ha csak egy "return;" kerül a végére -- mint amiről a cikkben is szó van -- ugyanolyan döglött marad. És akkor is, ha egy "true;" beszalad a változó deklaráció utáni sorba... vagy bárhová, ha jobban belegondolok. A muksó által készített módosítás nem befolyásolhatta volna a dead code elimination-t.

A számok:


IE9:
----

cordic:                  1 ms
cordic a return;-nal: 20,3 ms
cordic a true;-val:   19,5 ms

Chrome:
-------

cordic:                9,5 ms
cordic a return;-nal:  9,6 ms
cordic a true;-val:    9,6 ms

Opera:
------

cordic:                7,7 ms
cordic a return;-nal:  7,7 ms
cordic a true;-val:    7,9 ms

Azt még értem, hogy a dead code nélkül miért lehet(ne) az IE9 gyorsabb.

A "cordic a return;-nal" és a "cordic a true;-val" miért kétszer lassabb IE9 esetén a többi böngésző eredményénél? Valaki esetleg elmagyarázhatná nekem, tudatlannak.

--
trey @ gépház

Nézd meg fönt azt a 2 diff-et! Ha tényleg dead-code-elimination müxik az IE9-ben, akkor az igen rosszul működik. Azzal a "true"-val meg "return"-nel az új függvény még ugyanúgy dead-code, mint az eredeti.
Nagyon gyenge védekezés a M$ részéről, mert kvázi beismerték, hogy a "dead-code-elimination" kizárólag a SunSpider-ben található cordicsincos() rutinra működik.

két fő dolgot mondanak:

1. a dead code elimination miatt gyors az ie9
2. sunspider szar, mert a real-web tök más

ebből nem az a konzekvencia, hogy akkor real weben sokkal gyengébb lesz az ie9? mert nem ezt mondják.

Nekem erről az jut eszembe, mikor voltak olyan "élelmes" hallgatók (nem tartoztam közéjük) akiknek úgy ment át a progházijuk a teszten, hogy a programjuk annyit csinált, hogy kiprintelte a végeredményeket... :D

Ez bizonyára a hftest volt. Előző félévben már azt csinálták, hogy csináltak egy webes rendszert, és azon kellett beadni a beadandókat. És ott már nem lehetett shellscripttel trükközni, egyrészt csak C (vagy C++) kódot fogadott el, másrészt a system és társait letiltották.

Egyébként az is szép volt, hogy ugye elvileg olyan bemenettel tesztelnek amit te nem kapsz meg. Viszont ha stderr-re kiírattad a bemenetet, azt már megkaptad. (Stdout-ot azt ugye a saját rendszerük elkapta.)

A konkrét feladattal kapcsolatban csak annyit, hogy nem kellett teljes regex engine-t írni, egy max 10 (vagy akörüli) állapotú finite state machinet kellett írni.

--
Don't be an Ubuntard!

Viszont ha stderr-re kiírattad a bemenetet, azt már megkaptad.

Nekem 1 éve volt prog2-m, de ha jól emlékszem változó bemeneteket adtak, viszont hibakeresésnél természetesen jól jött az aktuális, rosszul kezelt bemenet :)

------------------
My Open-Source Android "Projects"

IE9 Chakra JavaScript Team Hosting a Q&A Session Tomorrow

The IE9 team announced that they’ll be hosting an open Q&A session via Twitter where developers can ask questions to the Chakra engineers about the new JavaScript engine.

In conjunction with the release of Platform Preview 7, we wanted to give the community the opportunity to ask questions of some of our IE and Chakra engineers. So we’re going to host a 2-hour Q&A chat on Twitter tomorrow morning beginning at 9am PST.

They’ll be fielding questions starting tomorrow Thursday, November 18th from 9-11am PST and you can participate by sending your questions to @ie and using the hashtag #ie9.

http://windowsteamblog.com/ie/b/ie/archive/2010/11/17/meet-the-chakra-t…

(via ajaxian.com )