volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 21.01.2009, 20:57 Titel: naked Functions |
|
|
Eigentlich war es nur ein Test, welche Funktion schnellere die Quersumme einer Zahl berechnet.
Diese: Code: | Function Quersum_i (n As Integer) As Integer
Dim As Integer i, tmp = Abs(n) 'Abs(n) damit das Ergebnis positiv wird
While tmp ' Abbruch bei n = 0
i += tmp Mod 10 ' plus Einerstelle
tmp \= 10 ':10 = eine Dezimalstelle nach rechts
Wend
Function = i
End Function |
oder diese elegante rekursive Funktion: Code: | Function Quersum_r (n As Integer) As Integer
If n Then Function = Abs(n Mod 10) + Quersum_r(n\10)
End Function |
War aber eigentlich klar!
Rekursive Programme haben in Basic keine gute Performance.
Durch die wiederholten Funktionsaufrufe wird immer wieder derselbe Prozedureintrittscode bearbeitet und jedes Mal Variablen auf dem Stapel (Stack) gesichert, und das dauert nun mal seine Zeit.
Hier ist der ganze Test:
http://www.freebasic-portal.de/index.php?s=fbporticula&mode=show&id=788
Nächster Versuch in Inlineasm: Code: | 'in Assembler ist das mehr Quelltext, aber wesentlich kürzerer schnellerer Code ;)
Function Quersum_asm (n As Integer) As Integer
Dim As Integer tmp = Abs(n) 'Abs(n) damit das Ergebnis positiv wird
Asm
mov eax, [tmp]
mov ecx, 10
xor ebx, ebx '= i
.balign 16
nochmal:
Xor edx, edx
idiv ecx 'tmp \= 10
add ebx, edx 'i += tmp Mod 10
or eax, eax 'While tmp<>0
jnz nochmal 'Wend
mov eax, ebx
mov [Function], ebx
End Asm
End Function |
Na bitte, mehr als 2x so schnell, hier lohnt sich Asm ..
Da gab es doch noch was Neues, "nackte Funktionen".
Am Anfang und Ende einer Prozedur werdem vom Kompeiler einige, organisatorisch wichtige, Befehle eingesetzt.
Dieser 'Prolog' und 'Epilog' sichert die Datenübergabe, erstellt Speicherplatz für lokale Variable und sorgt für einen sauberen Abgang aus der Prozedur.
Mit einer nakten (naked) Prozedur muss man auf diesen Komfort zum größten Teil verzichten und selbst Hand anlegen...
Achtung die naked - Option wurde erstmals in die FBC 0.21 Version vom Dezember 2008 eingebaut.
Specken wir den Aufruf der Funktion mal ab. Code: | Function Quersum_nak Naked (n As Integer) As Integer
Asm
'ABS(n)
mov eax, [esp+4] 'n direkt vom Stack holen
mov ebx, eax 'n sichern in ebx
neg eax 'eax = -eax
cmovs eax,ebx'wenn eax negativ war, n aus ebx holen
mov ecx, 10
xor ebx, ebx '= i
.balign 16
weiter:
Xor edx, edx
idiv ecx 'tmp \= 10
add ebx, edx 'i += tmp Mod 10
or eax, eax 'While tmp<>0
jnz weiter 'Wend
mov eax, ebx 'eax hat Rückgabewert
ret 4 'bei stdall Stack hier bereinigen
End Asm
End Function |
Na ja, nur 5% (80 ms) besser, aber immerhin ..
Bei grafischen Anwendungen könnte das ein Bild mehr pro Sekunde sein.
Hier gibt es das Listing:
http://www.freebasic-portal.de/index.php?s=fbporticula&mode=show&id=787 _________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|