tag:blogger.com,1999:blog-681966504815228096.post8884378018372667385..comments2017-10-20T14:45:42.480-07:00Comments on nino porcino: Saltarelle vs JSIL -- Raytracer DemoAntonino Porcinohttp://www.blogger.com/profile/11749887898485061928noreply@blogger.comBlogger3125tag:blogger.com,1999:blog-681966504815228096.post-37304702696628247842013-03-10T16:41:40.999-07:002013-03-10T16:41:40.999-07:00It's interesting to hear that such a simple ch...It's interesting to hear that such a simple change on Saltarelle's end caused a performance hit; I'd encourage you (if not Saltarelle's developer) to file bugs with the developers of V8 and SpiderMonkey in scenarios where it seems like a change shouldn't cause a performance hit. At the very least, sometimes they can provide guidance on how to coax their runtimes into doing the right thing; in other cases it can result in fixes.<br /><br />Thanks again for taking the time to do this test and write it up. I appreciate it :)Kevin Gaddhttps://www.blogger.com/profile/04689186557672996705noreply@blogger.comtag:blogger.com,1999:blog-681966504815228096.post-41944595528473158172013-03-07T04:02:13.906-08:002013-03-07T04:02:13.906-08:00Hi Kevin, that you for your comment.
Yes the code...Hi Kevin, that you for your comment.<br /><br />Yes the code is almost unmodified, apart from missing types I had to change the pixel writer routine to make it work with Canvas directly.<br /><br />I agree, now that I reread it, the "unnecessary layer of abstraction" is misleading, it leads to think that there is a sort of IL emulator which is not the case. <br /><br />I started to think of JS runtime issue too, recently there was a new Saltarelle release which changed how .NET methods are simulated and that lead to a significant drop in performance in the Raytracer, not completely justified by the change introduced. (For curiosity, it's because .NET methods are no longer in the prototype, eg mystring.Length() is now compiled as something like ss.StringLength(mystr);)<br /><br />BTW, your work with JSIL is amazing, when I have to impress people with C# running in the browser I usually show them "Escape Goat"!<br /><br />Antonino Porcinohttps://www.blogger.com/profile/11749887898485061928noreply@blogger.comtag:blogger.com,1999:blog-681966504815228096.post-55698553235618656132013-03-06T19:10:31.083-08:002013-03-06T19:10:31.083-08:00Cool to see someone do this comparison - I didn...Cool to see someone do this comparison - I didn't realize Saltarelle was able to compile unmodified application code in this fashion (or did you have to modify the actual code? It looks equivalent to me).<br /><br />A couple complaints though;<br /><br />first of all while your measurements for execution time seem more or less right, your conclusions about performance are totally wrong. I don't think you spent any time looking in the profiler or even reading the output.<br /><br />There's no 'unnecessary layer of abstraction' anywhere in the JSIL output that results in any performance degradation; you can easily confirm this by looking at the generated JS from Saltarelle and JSIL for the functions that show up as hotspots in the profiles, they are equivalent. For example:<br /><br />// Saltarelle<br />$simpleray_$RayTracer.$checkIntersection = function(ray) {<br /> for (var $t1 = 0; $t1 < $simpleray_$RayTracer.$objects.length; $t1++) {<br /> var obj = $simpleray_$RayTracer.$objects[$t1];<br /> // loop through objects, test for intersection<br /> var hitDistance = obj.intersect(ray.$);<br /> // check for intersection with this object and find distance<br /> if (hitDistance < ray.$.closestHitDistance && hitDistance > 0) {<br /> ray.$.closestHitObject = obj;<br /> // object hit and closest yet found - store it<br /> ray.$.closestHitDistance = hitDistance;<br /> }<br /> }<br /> ray.$.hitPoint = $simpleray_Vector3f.op_Addition(ray.$.origin, $simpleray_Vector3f.op_Multiply(ray.$.direction, ray.$.closestHitDistance));<br /> // also store the point of intersection <br />};<br /><br />// JSIL<br /> $.Method({Static:true , Public:false}, "CheckIntersection", <br /> $sig.make(0x253A, null, [$jsilcore.TypeRef("JSIL.Reference", [$asm01.TypeRef("simpleray.Ray")])], []), <br /> function RayTracer_CheckIntersection (/* ref */ ray) {<br /><br /> for (var a$0 = $thisType.objects._items, i$0 = 0, l$0 = $thisType.objects._size; i$0 < l$0; i$0++) {<br /> var obj = a$0[i$0];<br /> var hitDistance = obj.Intersect(ray.value);<br /> if (!((hitDistance >= ray.value.closestHitDistance) || (hitDistance <= 0))) {<br /> ray.value.closestHitObject = obj;<br /> ray.value.closestHitDistance = hitDistance;<br /> }<br /> }<br /> ray.value.hitPoint = $T01().op_Addition(ray.value.origin, $T01().op_Multiply(ray.value.direction, ray.value.closestHitDistance));<br /> }<br /> );<br /><br />Obviously there are differences in variable names, Saltarelle includes comments, and a couple minor semantic differences (JSIL produces slightly more opaque, but faster code for the foreach construct) but there is no unnecessary abstraction in either function. Both compilers are preserving meaning and not adding any unnecessary overhead to this operation.<br /><br />The reason the JSIL version is slower is simply due to modern JS runtimes still being unable to effectively inline simple functions and generate efficient in-memory data structures in a variety of cases. Saltarelle's output is much easier to inline since it does not actually implement the full semantics of .NET. The *actual code* generated by both compilers to do things like loops and computations is effectively equivalent, and you are measuring the performance hit(s) caused by JavaScript runtimes' failure to inline it in all cases.<br /><br />It's definitely true that the JSIL output is pretty big, but more or less for the same reason: You compiled a real .NET application, so you got all the junk that comes along with it: .NET types, etc. The fact that you had to implement Console and Random yourself kind of goes to illustrate that this is probably the wrong way to compare these two tools: Saltarelle is perfect if your goal is to build something with a C#-like language, but the wrong choice if you want to port an existing application. Likewise, I would not recommend JSIL to someone who's aiming to build an app from scratch for the web - the burden of real .NET would just get in your way.Kevin Gaddhttps://www.blogger.com/profile/04689186557672996705noreply@blogger.com