Increment, Decrement

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Increment, Decrement

Beitrag von cxAlex »

In meinen Sources muss ich immer wieder (wie die meiste ^^) eine Variable oder einen Zeiger Inkrementieren oder Dekrementieren (also z.B. x+1, x-1). Nun hab ich mir dafür Macros geschrieben, Inc(), Dec(), IncP(), DecP() die dasselbe in ASM machen. Und siehe da, das ganze ist sogar schneller als mit PB. Das ganze funktioniert mit Pointern und Integern unter 32 und 64 Bit:

Code: Alles auswählen

Macro IncP(_Var)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !INC dword[p.p_#_Var]
  CompilerElse
    !INC qword[p.p_#_Var]
  CompilerEndIf
EndMacro

Macro DecP(_Var)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !DEC dword[p.p_#_Var]
  CompilerElse
    !DEC qword[p.p_#_Var]
  CompilerEndIf
EndMacro

Macro Inc(_Var)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !INC dword[p.v_#_Var]
  CompilerElse
    !INC qword[p.v_#_Var]
  CompilerEndIf
EndMacro

Macro Dec(_Var)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !DEC dword[p.v_#_Var]
  CompilerElse
    !DEC qword[p.v_#_Var]
  CompilerEndIf
EndMacro


#Test = 1000000

Procedure Test()
  TestString.s = "Das ist ein TestString 0"
  *char.Character
  For i = 1 To #Test
    *char = @TestString
    While *char\c<>'0'
      *Char + 1
    Wend
  Next
EndProcedure

Procedure Test2()
  TestString.s = "Das ist ein TestString 0"
  *char.Character
  For i = 1 To #Test
    *char = @TestString
    While *char\c<>'0'
      IncP(char)
    Wend
  Next
EndProcedure



t = ElapsedMilliseconds()
Test()
t = ElapsedMilliseconds()-t
MessageRequester("Time", Str(t))


t = ElapsedMilliseconds()
Test2()
t = ElapsedMilliseconds()-t
MessageRequester("Time", Str(t))
Bei mir:

PB: 1907 ms
ASM - Macros: 1297 ms

Resultat: ASM ca. 1/3 schneller
Zuletzt geändert von cxAlex am 03.01.2009 17:37, insgesamt 1-mal geändert.
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

Ist bei mir gleich schnell. Circa ~78 auf 'nem Pentium D 3.00GHz.
Windows 10 Pro, 64-Bit / Outtakes | Derek
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag von cxAlex »

Probiers nochmal, hab den Source angepasst um besser vergleichen zu können.
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Da PB IMHO dasselbe erzeugt kann ich das auch nicht so recht glauben
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag von cxAlex »

Ok. Mein Fehler. Hab den Debugger nicht aus gemacht :oops:.
Trozdem ist die ASM - Variante bei mir immer noch leicht schneller:

#Test = 10000000
PB: 469 ms
ASM: 422 ms
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

PB erzeugt aber denselben ASM-Output, jedenfalls war das bisher so.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag von cxAlex »

Dazu kann ich nicht sagen weil ichs nicht weis, TROZDEM is der Code ohne Debugger bei mir 500 ms schneller:

Code: Alles auswählen

Macro IncP(_Var)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !INC dword[p.p_#_Var]
  CompilerElse
    !INC qword[p.p_#_Var]
  CompilerEndIf
EndMacro

Macro DecP(_Var)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !DEC dword[p.p_#_Var]
  CompilerElse
    !DEC qword[p.p_#_Var]
  CompilerEndIf
EndMacro

Macro Inc(_Var)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !INC dword[p.v_#_Var]
  CompilerElse
    !INC qword[p.v_#_Var]
  CompilerEndIf
EndMacro

Macro Dec(_Var)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !DEC dword[p.v_#_Var]
  CompilerElse
    !DEC qword[p.v_#_Var]
  CompilerEndIf
EndMacro


#Test = 100000000

Procedure Test()
  TestString.s = "Das ist ein TestString 0"
  *char.Character
  For i = 1 To #Test
    *char = @TestString
    While *char\c<>'0'
      *Char + 1
    Wend
  Next
EndProcedure

Procedure Test2()
  TestString.s = "Das ist ein TestString 0"
  *char.Character
  For i = 1 To #Test
    *char = @TestString
    While *char\c<>'0'
      IncP(char)
    Wend
  Next
EndProcedure

t = ElapsedMilliseconds()
Test()
t = ElapsedMilliseconds()-t
MessageRequester("Time", Str(t))

t = ElapsedMilliseconds()
Test2()
t = ElapsedMilliseconds()-t
MessageRequester("Time", Str(t))
Und bevor jetzt werd sagt "Den Vorteil kann man doch nirgends spüren":
Ich hab Codes wo man das merkt, Besonders wenn man noch an anderen Stellen optimiert.
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
c4s
Beiträge: 1235
Registriert: 19.09.2007 22:18

Beitrag von c4s »

...zumindest sind deine Macros bei mir auch ungefähr eine halbe Sekunde
schneller.
Naja bei 100.000.000 Loops.. :shock:
"Menschenskinder, das Niveau dieses Forums singt schon wieder!" — GronkhLP ||| "ich hogffe ihr könnt den fehle endecken" — Marvin133 ||| "Ideoten gibts ..." — computerfreak ||| "Jup, danke. Gruss" — funkheld
Benutzeravatar
Rings
Beiträge: 977
Registriert: 29.08.2004 08:48

Beitrag von Rings »

Kappes.
Im Asm-Output (siehe Compilerswitch /Commented )
steht ganz klar ein INC dword[ESP+X]

das heisst es kommt immer grad an wie der cache bestückt ist.
ansonsten ist die reine PB version sogar schneller da
sie mit dem Stack (ESP) arbeitet.
Rings hat geschrieben:ziert sich nich beim zitieren
Oliver1994
Beiträge: 321
Registriert: 15.06.2008 21:52

Beitrag von Oliver1994 »

Oh nein oh nein!

Meine Werte sind peinlich:

PB:7772
ASM:5188

^^Sorry aber mein PC ist halt nicht mehr der neuste!

Gruß

JENS
Antworten