Slashdot Mirror


Parrots, Pythons And Things That Go Splat

ajs writes "As you may know, there was a contest between Dan Sugalski and Guido van Rossum over the performance of Parrot running Python byte-code, and the loser was to take a pie in the face. Well, in the end it was between Dan and time and Dan lost... he was unable to get the Python bytecode translator to work sufficiently well for the contest (it was fast, but not complete), but when Dan conceded, Guido was gracious enough to decline to throw a pie, what a sport! The Perl community, however, was not quite so gracious (they wanted to see Dan take a pie for the team), and the final event ended up being a benefit for the Perl Foundation. Meanwhile, see Dan's Blog for details on what sorts of Parrot goodness came of this."

5 of 43 comments (clear)

  1. Both slower than Java tho... by Anonymous Coward · · Score: 0, Insightful

    ...of course, one would not expect late-bound languages like Perl or Python to compete with Java in that regard. But in my experience PythonC runs my benchmarks at just over 1/10 the speed of HotSpot. Surely they can improve on that.

  2. No chance in hell by Anonymous Coward · · Score: 5, Insightful
    I have faith Parrot will be as good as the other VMs (Java, Mono)
    These languages make certain assumptions about typing and binding that Python and Perl do not. Additionally, Java's class structure is much *much* more time-efficient (though I rather like it less) than Python's memory-efficient proto-based object structure. It's the nature of the languages. It's why they're SCRIPTING languages. They traded speed for ease of coding. Which is just fine. But don't oversell them, you just look foolish.
  3. Re:Benchmarks aren't everything by Electrum · · Score: 2, Insightful

    My mistake. I totally missed your point the first time.

  4. Type inference (was Re:No chance in hell) by Eivind+Eklund · · Score: 3, Insightful
    Moderators, PLEASE DO NOT MODERATE INSIGHTFUL UNLESS YOU KNOW THE SUBJECT AREA! The text quoted below (parent of this article) is full of simplistic (and wrong) assumptions, and do NOT deserve an "Insightful".

    These languages make certain assumptions about typing and binding that Python and Perl do not. Additionally, Java's class structure is much *much* more time-efficient (though I rather like it less) than Python's memory-efficient proto-based object structure. It's the nature of the languages. It's why they're SCRIPTING languages. They traded speed for ease of coding. Which is just fine. But don't oversell them, you just look foolish.

    Having looked reasonably deeply at the type inference space, this comment seems wrong to me. The division between "scripting languages" and "compiled languages" is superficial. The idea that doing type declarations etc makes a crucial difference is superficial. And the idea that a class is implemented the same way in the compiled code as in the executed code - that's extremely superficial.

    The static (visible, programming level) declarations of type information in Java/C++/etc makes it much easier to write a compiler that generates reasonably fast code. You just follow the type specifications, leave all abstract types as the abstract types, and use a doubly indirected jump table to resolve abstract methods.

    I've seen a non-optimizing C compiler done in three days of intense work by one programmer - and the inheritance/object/abstract methods addition here is fairly trivial.

    Similarly, a simple interpreter is easy to write. I've done one in a day for a simple Lisp dialect. And yeah, they're slow.

    However, this stuff is 1950s technology. FORTRAN came in 1956 (with an amazing optimizing compiler that competed with hand-written assembly), Lisp with an interpreter in 1958-1959 (depending a bit on how you interpret the history). What's interesting today is what we can do with type inference, constant propagation, partial evaluation, memory and cache use optimization, etc. And then the picture changes.

    To be able to handle abstract types effectively, you need to do type inference to find out what actual method will be called by each abstract method call, in order to be able to do partial evaluation and constant propagation through the methods. And - guess what - that's the same stuff you need to do for all methods and variable lookups in a fully dynamic language.

    In other words: The same problem is there for compiler writers, and has to be solved for a fast compiler. You get SOME extra information from the type declarations, but this information is usually the same you would get for the first pass or three of the type inference engine.

    So, for good compiling/execution of Java/C#, I would start doing speculative execution with partially evaluated expressions taking the place of variables in my execution path, resolving these to constants when I can. Different code prefixes (relevant system state parts) result in re-evaluation of the pseudo method call, noting if this makes a difference in evaluation, and either registering the prefix on a new resolution block or adding it to an old resolution block. When all resolution blocks have become non-changing (no more information is being aquired through partial evaluation), I'd stop the partial evaluation and do (virtual machine) code generation.

    For good compiling/execution of Ruby/Python/Perl, I would start doing speculative execution with partially evaluated expressions taking the place of variables in my execution path, resolving these to constants when I can. Different code prefixes (relevant system state parts) result in re-evaluation of the pseudo method call, noting if this makes a difference in evaluation, and either registering the prefix on a new resolution block or adding it to an old resolution block. When all resolution blocks have become non-changing (no more information is being aquired through partial ev

    --
    Doubting the existence of evolution is like doubting the existence of China: It just shows that you're uninformed.
    1. Re:Type inference (was Re:No chance in hell) by Anonymous Coward · · Score: 1, Insightful
      This astonishingly understates the difficulty in dealing with runtime typing and binding. Consider the function:
      func foo(x) {return bar(x) + 3;}
      So... what type is x? An int? A string? A stream? You can't tell because it depends on what's passed to bar. If bar's around, you could use this to infer the type of x for foo. But for many such languages, bar is loaded at runtime *and* in some of them, the type of x passed into bar can change. Compiler researchers have been arguing for a variety of runtime analysis tools to determine the type of objects and perform optimization appropriately; but I've not seen much come of it. Because it's really really hard to do.

      But you didn't even address the grandparent's more salient point: Python uses a proto-based object model. These things are cool. But they're slow. I know of four other languages with a proto model: Self, JavaScript, NewtonScript, and Snarf (a Lisp add-on). The most efficient implementation of a proto-based model was probably NewtonScript, complete with certain caching mechanisms to deal with its essential problem, which is that it's O(slots) to look up a slot value, rather than O(1) in Java. But you can only go so far, particularly if slots are changed a lot. Proto models are a classic example of trading speed for size. They're exceptionally memory efficient, but they're slow.

      The grandparent knew exactly what he was talking about, and you're just tossing out promises which have been made since the '70s. Let's get serious here.