Lua: Bitoperationen mit Bit32 oder Multiplikation

#3161113
Lesenswert?

Hallo,
wenn ich aus zwei words ein dword machen will, kann ich ja schreiben
1
dwo = lowo + 0x10000 * hiwo

das modul 'bit32' bietet aber direkte Bit-Ops an (bei 5.2 schon fest 
dabei)
1
dwo = bit32.bor(lowo, bit32.lshift(hiwo,16))

Wie ist das in Sachen Lesbarkeit und Rechengeschwindigkeit zu 
vergleichen?
Mir persönlich gefällt die erste Variante besser.

Ok, beim Aufteilen müsste man schreiben
1
hiwo= math.floor( dwo / 0x10000)
2
lowo= dwo - 0x10000*hiwo
#3161185
Lesenswert?

Jürgen W. schrieb:

> Wie ist das in Sachen Lesbarkeit und Rechengeschwindigkeit zu
> vergleichen?

Sieh zu, dass du einen Blick auf den erzeugten Code kriegst.

Für einen ordentlichen Compiler ist es ein leichtes, für beide Versionen 
den gleichen Code zu erzeugen. Das Vereinfachen derartiger 
Multiplikationen zu Bitoperationen bzw. zu einfacheren Versionen, die 
dasselbe Ergebnis haben, machen übliche Compiler seit mehr als 40 Jahren 
standardmässig. Ist ja auch kein wirkliches Problem.
#3161220
Lesenswert?

Jürgen W. schrieb:
> Wie ist das in Sachen Lesbarkeit und Rechengeschwindigkeit zu
> vergleichen?
> Mir persönlich gefällt die erste Variante besser.

Dann ist ja schon gewählt, oder?

Oder hast du Performance Probleme? z.B. CHDK lässt ja Lua auf den Canon 
Digicams laufen, die sind nicht besonders schnell...

Wenn du die Performance messen willst: Mach eine Schliefe, 10'000 
durchläufe und miss die Zeit...


mfg Andreas
Gast #3161321
Lesenswert?

Karl Heinz Buchegger schrieb:
> Das alleine ist noch kein Hindernisgrund.

Eher doch, und Deine obige Bemerkung

>Sieh zu, dass du einen Blick auf den erzeugten Code kriegst.

hat mich schon etwas erschreckt.

Lua wird, wie auch andere Scriptsprachen wie Python und Ruby, kein 
Assemblerlisting erzeugen können, dass man sich ansehen kann. Auch wenn 
intern Bytecode erzeugt wird -- erstens wird man den nicht zu Gesicht 
bekommen, und zweitens würde man damit wohl nicht viel anfangen können, 
soferm man keine entsprechende Virtuelle Maschiene ist.

Und da die erwähnten Sprachen eher jung sind, kann sich bezüglich 
Performance mit jeder neuen Version viel ändern. So macht es eher wenig 
Sinn, überhaupt nach Performance zu fragen, solange man nicht ein 
Problem damit hat. Bleibt also das Kriterium der Lesbarkeit.
#3161341
Lesenswert?

>Dann ist ja schon gewählt, oder?
Nicht ganz. In einigen Fällen zB bit setzen oder löschen ist bit32 schon 
angenehmer. Die Frage ist eher ob man überhaupt noch diese 
bit-Konstrukte nimmt. Ich bin halt von C geprägt.
Auch ist zu bedenken, dass man zu Lua 5.1 kompatibel sein möchte.

>Und da die erwähnten Sprachen eher jung
Trifft bei Lua nicht zu
#3161364
Lesenswert?

Salewski, Stefan schrieb:

> Eher doch, und Deine obige Bemerkung
>
>>Sieh zu, dass du einen Blick auf den erzeugten Code kriegst.
>
> hat mich schon etwas erschreckt.

Da wusste ich noch nicht, dass Lua 'interpretiert' wird.
Aber wie alle ernst zu nehmende Interpreter-Ansätze, wird der 
Programmtext ja zumindest in einen Zwischencode übersetzt. Und genau da 
ist dann der Punkt an dem man derartige Optimierungen unterbringt.

Ob der Lua Compiler das macht oder nicht, weiß ich nicht.

> Bleibt also das Kriterium der Lesbarkeit.
Ganz genau.
Gast #3161373
Lesenswert?

Jürgen W. schrieb:
>>Und da die erwähnten Sprachen eher jung
> Trifft bei Lua nicht zu

Nun ja, was ist jung?

Ruby ist gerade 20 geworden, Python ist etwas älter -- Teenager halt, 
noch keine ausgereiften Persönlichkeiten. Lua würde ich auch so um die 
20 schätzen. Ruby ist "jung", weil es eine sehr komplexe Sprache ist und 
die Entwicklung langsam voranschreitet. Von Version 1.8.x nach 1.9/2.0 
hat sich viel getan, insbesondere ist durch den Bytecode-Interpreter die 
Performance stark gestiegen und hat nahezu zu Python aufgeschlossen. 
Wichtig ist ja  noch, dass es meist verschiedene Interpreter gibt -- 
etwa JRuby oder das experimentelle Topaz, und für Python etwa PyPy, was 
wohl schon eher ein Compiler ist. Daher macht die allgemeine Frage nach 
Performance wenig Sinn.

Und nun habe ich doch nachgesehen -- Lua ist auch gerade 20 geworden

http://de.wikipedia.org/wiki/Lua
#3161411
Lesenswert?

Mit jung hätte ich Sprachen wie angelscript eingestuft. 20 Jahren sind 
ja schon eine Menge.
Als ich mit C Mitte der 80er anfing, war diese gerade 15 Jahren alt, und 
mir erschien das nicht "jung".
Von Lua habe erst vor ein paar Jahren gehört, als ein Ex-Kollege davon 
schwärmte (Spiele-Programmierer)
Die Bit-Operationen sind nicht das einzige Problem, andere Sachen 
(Array-Indizierweise) machen mir auch zu schaffen. Aber die Einfachheit, 
Erweiterbarkeit und Stabilität der Sprache überzeugt.
Moderator #3161655
Lesenswert?

Bei Interpretern (auch Bytecode-Interpretern) spielt die Zeit für die
Ausführung primitiver Rechenoperationen kaum eine Rolle, zumal auf einem
PC Addition, Multiplikation, Bit-Or und Bit-Shift sowieso ungefähr
gleich lang dauern.

Wesentlich mehr Zeit brauchen i.Allg. die Dekodierung der Befehle, das
Auffinden von Variablen und die Verwaltung des internen Interpreter-
zustands.

Hier sind die Disassemblies des vom Compiler generierten Bytecodes für
die beiden Anweisungen (du erhältst sie mit luac -l test.lua):

1
  dwo = lowo + 0x10000 * hiwo
2
        10      [7]     GETTABUP        4 0 -5  ; _ENV "lowo"
3
        11      [7]     GETTABUP        5 0 -3  ; _ENV "hiwo"
4
        12      [7]     MUL             5 -10 5 ; 65536 -
5
        13      [7]     ADD             4 4 5
6
        14      [7]     SETTABUP        0 -9 4  ; _ENV "dwo"

1
  dwo = bit32.bor(lowo, bit32.lshift(hiwo,16))
2
        10      [8]     GETTABUP        4 0 -2  ; _ENV "bit32"
3
        11      [8]     GETTABLE        4 4 -10 ; "bor"
4
        12      [8]     GETTABUP        5 0 -5  ; _ENV "lowo"
5
        13      [8]     GETTABUP        6 0 -2  ; _ENV "bit32"
6
        14      [8]     GETTABLE        6 6 -11 ; "lshift"
7
        15      [8]     GETTABUP        7 0 -3  ; _ENV "hiwo"
8
        16      [8]     LOADK           8 -12   ; 16
9
        17      [8]     CALL            6 3 0
10
        18      [8]     CALL            4 0 2
11
        19      [8]     SETTABUP        0 -9 4  ; _ENV "dwo"

Der Code sollte dank der vom Compiler eingefügten Kommentare weitgehend 
selbsterklärend sein.

Die erste Variante braucht auf meinem Pentium 4 mit 3,2 GHz 143 ns. Die
zweite Variante ist länger, macht mehr zeitaufwendige Symbol-Lookups und
braucht deswegen mit 533 ns deutlich länger.

Zwei Lookups kann man in der zweiten Variante einsparen, indem man
bit32.bor und bit32.shift am Programmanfang Variablen zuweist, so dass
bei der eigentlichen Rechenoperation bit32 nicht mehr nachgeschlagen
werden muss. Dann dauert diese Variante nur noch 462 ns, ist aber immer
noch deutlich langsamer als die erste Variante.
Gast #3161829
Lesenswert?

Yalu X. schrieb:
> Hier sind die Disassemblies des vom Compiler generierten Bytecodes für
> die beiden Anweisungen

Puh -- da habe ich echt mal was gelernt hier im Forum.

Das hätte ich nun echt nicht erwartet, dass man fur Lua den 
kommentierten Bytecode ansehen kann.
Ich denke mal für Ruby geht das nicht, jedenfalls habe ich da noch nie 
von gehört -- ich werde aber demnächst mal danach suchen, auch für 
Python.

Aber meine anderen Argumente entkräftet das nicht wirklich -- mit jeder 
neuen Interpreterversion oder mit einem anderen Interpreter/Compiler 
kann das ganz anders aussehen, und wenn man Sprachen wie Lua/Python/Ruby 
nutzt steht die Ausführungsgeschwindigkeit meist nicht im Vordergrund. 
Die Lesbarkeit/Verstehbarkeit ist dann wichtiger.
Moderator #3161969
Lesenswert?

Auch die Compiler-Entwickler brauchen ja irgendwelche Tools, mit denen
der vom Compiler erzeugte Bytecode in lesbarer Form angezeigt werden
kann. Deswegen muss entweder der Compiler selbst die Möglichkeit bieten,
Assembler-Quellcode zu erzeugen, oder es gibt einen Disassembler, oder
beides. Da diese Tools sowieso schon existieren, sind sie in Opensource-
und oft auch in Closedsource-Toolchains auch für den Compiler-Anwender
verfügbar.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren