Posted By: dcuccia | Aug 30th, 2008 @ 5:56 PM
page 1 of 1
Comments: 20 | Views: 1616
Just saw this article on the TraceMonkey complier for FF 3.1, which allows Javascript language features to "achieve a speedup of 22x."

Knee-jerk reactions:
  1. "Hey, no fair!"
  2. JSC and Volta just got more relevant for cross-platform RIAs
Any thoughts?
Bass
Bass
www.s​preadfirefox.c​om/5years/
Webkit has also greatly improved their JavaScript performance lately with a new virtual machine. What would be interesting is if Microsoft made a way to "compile" .NET into JavaScript I think, that Volta sounds really cool. Or if there was a standard virtual machine bytecode language that JavaScript compiled down to, and the web site could send directly to the browser for execution. It'll happen probably.
 "near native performance" I don't think it's that near as it sounds Smiley
evildictaitor
evildictaitor
if( !succeed( try() ) ) { while(true) try(); }
"Near C performance" on carefully selected algorithms. This fails to take into account:

a) The general cost of cleanup of variables (Garbage collection)
b) The time cost of compilation (Just in time means that large javascript libraries will take seconds, not milliseconds out of your performance)
c) The fact that javascript is both untyped and dynamic, meaning that large amounts of indirections nessisarilly occur which will prevent C-speed performance from ever being achievable with javascript
d) In C, if you write to an array past memory, your program crashes or exposes horrific bugs in your app. Because javascript should never allow arbitrary pointer-based code to run on your system, it must nessisarilly include checks that C does not, and will therefore nessisarilly experience slow down on all array accesses for bounds checking - optimising some of these away is possible, but slows down the JIT.
e) The fact that javascript generally outputs by modifying a HTML DOM tree, which is large, unwieldy and needs to be re-rendered and balanced after every mutation, which is expensive compared to C which typically only modifies in-memory objects for algorithms.

So I'm going to cry FUD on the whole "nearly as fast as C" statement here.
littleguru
littleguru
<3 Seattle
I'm also suspicious about this claim. It sounds good but they probably checked it only on selected algorithms. C# is also having near C performance if you carefully craft the algorithms. It might also be faster than C.

Interesting to point out is that they say "unoptimized C" code, which might be reaaaaaaaaally slow.

But cool to see that JavaScript gets more performance.
evildictaitor
evildictaitor
if( !succeed( try() ) ) { while(true) try(); }
"Faster than C?" I think you'll find that these are just compiler optimisations, not that the code is actually faster.

For example, from (pseudo) Spec#:


ensures result > 0
ensures (p == q) implies result = 0
public int Distance(Point! p, Point! q){
  return (int)Math.Sqrt( (p.x - q.x) * (p.x - q.x) + (p.y - q.y) * (p.y - q.y) );
}

requires p > 0
ensures p == 0
public int factorial(int p){
  if(p == 0) return 1;
  return p * factorial(p - 1);
}


public static void main(){
  int i = 7;

  // Spec# should be able to avoid the if( !(p > 0) ) throw new ArgumentException("p > 0 assertion failed"); step here
  // because it knows the parameter here. In C this would typically happen inside the function.
  Console.WriteLine( factorial( i ) );

  // Spec# can probably optimise away this entire function, since distance contains no side-effects and the first ensures
  // defines the result of the function.
  Console.WriteLine( distance(new Point(i, i), new Point(i, i) ));
}

Note that while this is "better than C performance", it's not better than an ideal C representation of the program:

int factorial(int f){
  if(f == 0) return 1;
  return factorial(f - 1) * f;
}
void main(){
  printf("%d\n0", factorial(i));
}

But is better than a non-ideal version of the program:

int factorial(int f){
  assert(f < 0);
  if(f == 0) return 1;
  return f * factorial(f - 1);
}

int distance(struct Point* p, struct Point* q){
  assert(p != NULL);
  assert(q != NULL);
  return (int)sqrt( (p->x - q->x) * (p->x - q->x) + (p->y - q->y) * (p->y - q->y) );
}


void main(){
  int i = 7;
  struct Point* a, b;

  printf("%d\n", factorial(i));

  a = malloc(sizeof(Point));
  b = malloc(sizeof(Point));

  a->x = i;
  a->y = i;
  b->x = i;
  b->y = i;

  printf("%d\n", distance(a, b));

  free(a);
  free(b);
}




Because C is so close to assembly language, it's fairly simple to deconstruct assembly language into C. Consequently any high-level language that runs "faster than C" is usually lying, because the high level language can be decomposed to assembler and recomposed to C, which by-defintion runs in the same speed. High level languages have lots of benefits, but when there are additional constraints such as garbage collection, C will nearly always win in a straight battle of which has the higher theoretical speed for an algorithm.
littleguru
littleguru
<3 Seattle
Isn't object construction faster in C# than in C++ (or I could construct something like this). I could write a sample that only does that in both languages and compare... hehe.

If you want to proof something you can always find a sample where the one or the other platform|language wins and in the end, in real-life, it doesn't hold at all.
Sven Groot
Sven Groot
My name has 9 letters. Coincidence? I think not...
Faster than C?" I think you'll find that these are just compiler optimisations, not that the code is actually faster.

If the C# compiler (or JIT compiler) produces faster assembly code than the C compiler for the same algorithm, then in my opinion that means C# is faster than C for that scenario. That you could write a better algorithm in C with a lot of effort is irrelevant in the real world.
evildictaitor
evildictaitor
if( !succeed( try() ) ) { while(true) try(); }
With the 'new" keyword, almost certainly. With RAII stack initialization, probably not

// C++
void main(){
  Point* p = new Point(4,4);
  delete p;
}

pseudo-turns into:
  1. get me 8 bytes of data on the heap (a bit expensive, but not hugely)
  2. call the constructor for point  (relatively cheap)
  3. call the destructor of point (relatively cheap)
  3. free the data (almost no cost)

Total cost: some.

// C++
void main(){
  Point p = Point(4,4);
}

pseudo-turns into:
  1. add 8 to ESP (almost free)
  2. call the constructor for point (relatively cheap)
  3. call the destructor for point (relatively cheap)

Total cost: very little.

// C#:

void main(){
  // let's pretend Point is a class not a struct-type for comparison
  Point p = new Point(4,4);
}

pseudo-turns into:
  1. call GC::allocate(8);  (relatively cheap)
  2. expand the heap if necessary (expensive - requires a full generational collection)
  3. register the object in the GC (relatively cheap)
  4. call the constructor for point (relatively cheap)
  5. Fall off the end of the program. Call destructors for everything (relatively cheap)

Total cost: a bit.
littleguru
littleguru
<3 Seattle
Which proofs my point that saying "something is faster than something else" doesn't really have a point. You had now 3 samples where I could pick a pair to say C# is faster or pick another pair where I would say C++ is faster.
evildictaitor
evildictaitor
if( !succeed( try() ) ) { while(true) try(); }
That definition of speed relies too heavilly on the competence of the programmer.

It's like saying that my new hypothetical language is much better than C because it uses quicksort, whereas some hypothetical C programmer uses bubblesort. Since my implementation is better, my language is faster at sorting an array.
CannotResolveSymbol
CannotResolveSymbol
{insert caption here}
C++ != C.

C has no concept of object construction, therefore object construction cannot be faster in C# than in C.  The closest equivalent to object construction in C is malloc(int size); which is the operating system's memory allocation routine:  C# has to call it in the process of allocating memory for an object on the heap.
littleguru
littleguru
<3 Seattle

That's why I said C++... AFAIK the new keyword in C++ invokes only a method that finds and allocates space (runs the constructor) and returns a pointer to that to me. But you are right: C++ adds stuff to C and that's why I compared C++ with C#.

Sven Groot
Sven Groot
My name has 9 letters. Coincidence? I think not...
No, you've got it the wrong way around. Your definition of speed relies on the competence of the programmer.

What I'm saying is, you write the same algorithm in both languages. So you use pretty much the same code both in C and in C#. If you write Bubblesort in C# and C and the C# version is faster, then I say C# is faster for Bubblesort, even though you could write a better sorting algorithm in C.

In many cases, in order to beat the optimizer of some other language, you would have to write extremely complex C code. That requires a level of skill that most real-world C programmers simply don't have.

And sometimes it can't be done at all. The Intel Fortran compiler is very aggressive in its use of vectorization and parallelization of loop constructs. In C it's nearly impossible (not completely impossible though) for the compiler to do the same thing because of all the invariants that become hard to prove in the presence of C-style pointers. In the Intel C compiler, you would need a lot of compiler directives to get it to produce the same assembly code as the Fortran compiler. With a compiler like MS Visual C++, it nearly never uses vector instructions and the only way to get it on par with the Intel Fortran compiler is using inline assembly and writing the vector instructions yourself.
evildictaitor
evildictaitor
if( !succeed( try() ) ) { while(true) try(); }
I don't want to a pedant, but malloc is a library function (sbrk is the OS version and is limited to whole pages).

For double-pedantry, C# doesn't use malloc because the GC uses it's own heap, roughly of the sort:

class GCHeap {
public:
  unsigned char* base, current;
  size_t capacity;

  void* allocate(size_t s){
    if(current - base > capacity) { fullCollect(); expandHeap(); }
    void* next = current;
    current += size;
    return next;
  }
}

Which is rather cheap to perform (amortized O(1) time). The rationale here is to avoid memory fragmentation.
evildictaitor
evildictaitor
if( !succeed( try() ) ) { while(true) try(); }
I'm happy to concede that a fortran program could achieve better than C performance. I'm going to be uneasy with C# getting better than C performance without using clever optimisations such as those found in Spec# (where I'll concede that this may be possible for normal programs). If a paper concluded this I would look rather carefully at the graphs and code to make sure they weren't cherry-picking examples . But for javascript? No. You've got to be having a laugh. Javascript is interpreted at runtime, dynamic, operates on a DOM which is graphically rendered, is not pointer based and is fully garbage collected. There is no hope in hell that it will ever be in the same league as C for speed.
littleguru
littleguru
<3 Seattle

The Firefox addition here compiles the JavaScript and stores it for later use. That's why they get the speed improvements. It's like ASP.NET's compiliation and storing for future requests - but on the client side.

I'm also rather suspicious when I get these kind of bold statements. Even a lot of the scientific papers say something that is tailored to their set of test data and doesn't expand to the real world... and if I read something like this on a website my suspicious alarm bell rings like crazy.

CannotResolveSymbol
CannotResolveSymbol
{insert caption here}
In the real world, you will see a performance boost.  Maybe not as dramatic as the 40x increase in certain benchmarks, but once a couple of performance regressions are worked out, Tracemonkey will be as fast or faster for any given script than the non-JIT Javascript interpreter.  And it should provide real-world performance gains, just like the .Net JIT compiler or the Java JIT compiler do:  it's more or less exactly the same concept.

I'm surprised that you didn't mention GWT or Script#.  GWT is more popular than Volta, Script#, and JSC combined.

It isn't too hard to envision an optimizing JavaScript JIT compiler being able to optimize computationally intensive code with no I/O or DOM manipulation to C-level performance figures. These optimizations are largely (but not completely) irrelevant to Web programming. I don't really see people flocking to reimplement their performance-critical code in JavaScript. They should be focusing on speeding up the DOM and browser rendering stacks instead.

page 1 of 1
Comments: 20 | Views: 1616
Microsoft Communities