Login
Newsletter
Werbung

Thema: Ruby-Bytecode-Compiler Rubinius 1.1 veröffentlicht

2 Kommentar(e) || Alle anzeigen ||  RSS
Kommentare von Lesern spiegeln nicht unbedingt die Meinung der Redaktion wider.
0
Von Kinch am Mo, 27. September 2010 um 20:45 #

Ob das tatsächlich schneller ist, hängt natürlich von den konkreten Implementierung ab. Aber dass es wirklich merkbare Laufzeitsunterschiede gibt, bezweifle ich.

Ruby erlaubt zum Beispiel, dass zur Laufzeit Methoden zu einer Klassen hinzugefügt werden kann. Das heißt, auch der kompilierte Code muss eine solche Dynamik erlauben. Zur Laufzeit muss also zum Beispiel bei einem Methodenaufruf erst nach der konkreten Methode „gesucht” werden. Sowas kostet unweigerlich Performance, ob das nun kompiliert ist oder nicht. Ähnlich sieht es bei anderen Funktionen aus, wie die dynamische Typisierung, Garbage Collector, etc…

Und spätestens bei der eval-Funktion wird der Ruby-Code sogar ganz klassisch interpretiert.

Ich kenne jedenfalls keine (VM-)Sprache, bei dem ein Maschienencode-Compiler zu relevanter Performance-Steigerung führte.

[
| Versenden | Drucken ]
  • 0
    Von panzi am Mo, 27. September 2010 um 21:32 #

    "Ich kenne jedenfalls keine (VM-)Sprache, bei dem ein Maschienencode-Compiler zu relevanter Performance-Steigerung führte."

    Auch und was ist mit den ganzen neuen JavaScript Engines? Die sind alle haushoch mehr performant als reine Interpreter. Ich weiß natürlich nicht wie gut dieser Ruby Compiler ist aber theoretisch kann man schon einiges rausholen, auch bei dynamischen Sprachen. Es gibt dazu entsprechende Google Tech Talks (über JRuby, denk ich). Natürlich ist eine statische Sprache immer schneller. Aber eine dynamische Sprache compiliert ist auch schneller als eine dynamische Sprache interpretiert. Wenn die Sprache nur glue Code zw. nativ implementierten Komponenten ist, ist das natürlich egal. Aber schau dir nur mal folgendes an:

    for (;;) {
    switch (code[pc]) {
    case INSTR1: CODE1; break;
    case INSTR2: CODE2; break;
    ...
    }
    ++ pc;
    }

    Wenn dieser Interpreter-Loop entsprechender Code gefüttert wird muss immer die Loop Logik zw. jeder Instruktion ausgeführt werden. Das Switch kann sogar auch noch relativ langsam umgesetzt werden (z.B. entsprechend: int _a = code[pc]; if (_a == INSTR1) { ... } else if (_a == INSTR2) ...). Ein Compiler kann z.B. in Code wie etw folgendes umwandeln:

    CODE1;
    CODE2;
    CODE1;
    CODE4;
    CODE2;
    ...

    Sprich viel weniger branches, und branches sollte man unbedingt vermeiden. Ich schätze auch das branch-prediction in Interpreter-Loops nicht gut funktionieren wird. I.d.R. kommt ja ständig eine andere Instruktion.

    [
    | Versenden | Drucken ]
Pro-Linux
Pro-Linux @Facebook
Neue Nachrichten
Werbung