Autor |
Beitrag |
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Mo 15.08.05 18:29
Poste mal die komplette Test-App, mir scheint es liegt an den Prozessoren.
Auf meinem Pentium M (1.5GHz) ist meine Routine ca. 10% schneller als die ASM-Teile von Dir....
Ich habe einfach '05-xxx-05' für alle xxx='Jan'...'Dez' jeweils 5.000.000 x aufgerufen, und dein ASM liegt bei 12.95 mein Zeugs bei 11.49, also ca. 10% langsamer.
Auf meinem 64bit AMD oder was ich da habe sieht die Sache wieder anders aus;
Alzheimer 9,709 ms
RetNyg Asm 9,467 ms
======================
Einigen wir uns auf: 3:3 für Dich! 
|
|
uall@ogc
      
Beiträge: 1826
Erhaltene Danke: 11
Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
|
Verfasst: Mo 15.08.05 18:54
Delphi-Quelltext 1: 2:
| mn := mn shl 8; mn := mn shr 8; |
wir wird gerade ganz schwindelig ;P (ok habs so auch irgendwann mal gemacht)
Delphi-Quelltext 1:
| mn := mn and $0000FFFF; |
ist dein freund
aber das nur nebenbei
_________________ wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
|
|
retnyg
      
Beiträge: 2754
SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
|
Verfasst: Mo 15.08.05 19:30
Einloggen, um Attachments anzusehen!
_________________ es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Mo 15.08.05 21:02
Ich habe das Testprogramm mal umgeschrieben, damit alle Funktionen hintereinander ablaufen.
Das liefert mein Laptop (PM 1,5 GHZ)
Quelltext 1: 2: 3: 4: 5: 6: 7:
| ConvertDateFastest1 5367: ConvertDateFastest 5208: AsmConvertDate16bit 6059: AsmConvertDate 5618: sprintConvertDate 5297: spConvertDate3 5318: spConvertDate 5368: |
Is schon lustig. Ach, egal. Nimmt sich sowieso alles nix.
Einloggen, um Attachments anzusehen!
|
|
retnyg
      
Beiträge: 2754
SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
|
Verfasst: Mo 15.08.05 22:32
alzaimar hat folgendes geschrieben: | Ich habe das Testprogramm mal umgeschrieben, damit alle Funktionen hintereinander ablaufen.
Das liefert mein Laptop (PM 1,5 GHZ) |
das mein 3.0'er: (etwas schneller  )
Zitat: |
ConvertDateFastest1 2125:
ConvertDateFastest 2125:
AsmConvertDate16bit 1938:
AsmConvertDate 1953:
sprintConvertDate 2031:
spConvertDate3 2047:
spConvertDate 2031:
ConvertDateFastest1 2125:
ConvertDateFastest 2125:
AsmConvertDate16bit 1937:
AsmConvertDate 1953:
sprintConvertDate 2032:
spConvertDate3 2046:
spConvertDate 2032:
|
alzaimar hat folgendes geschrieben: | Is schon lustig. Ach, egal. Nimmt sich sowieso alles nix. |
jo, das ist alles schon verdammt nah am optimum.
ich habe die funktionen übrigens drum nicht hintereinander laufen lassen, weil das die performance beeinflusst hat (selbe funktion war bei klcik auf nen anderen button ein stück langsamer)
_________________ es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Di 16.08.05 07:06
So, hab mein Pascal Code noch mal optimiert.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
| function ConvertDate(const ADate: String): AnsiString; var P: PByte; M: Integer; begin SetLength(Result, 8); PWordArray(Pointer(Result))[0] := PWordArray(Pointer(ADate))[0]; PByteArray(Pointer(Result))[6] := PByteArray(Pointer(ADate))[7]; PByteArray(Pointer(Result))[7] := PByteArray(Pointer(ADate))[8]; PByteArray(Pointer(Result))[2] := Ord('.'); PByteArray(Pointer(Result))[5] := Ord('.'); P := Pointer(Integer(ADate) + 3); if PIntegerArray(P)[0] = $2D6E614A then M := 1 else if PIntegerArray(P)[0] = $2D626546 then M := 2 else if PIntegerArray(P)[0] = $2D72614D then M := 3 else if PIntegerArray(P)[0] = $2D727041 then M := 4 else if PIntegerArray(P)[0] = $2D79614D then M := 5 else if PIntegerArray(P)[0] = $2D6E754A then M := 6 else if PIntegerArray(P)[0] = $2D6C754A then M := 7 else if PIntegerArray(P)[0] = $2D677541 then M := 8 else if PIntegerArray(P)[0] = $2D706553 then M := 9 else if PIntegerArray(P)[0] = $2D74634F then M := 10 else if PIntegerArray(P)[0] = $2D766F4E then M := 11 else M := 12; if M < 10 then begin PByteArray(Pointer(Result))[3] := Ord('0'); PByteArray(Pointer(Result))[4] := Byte(Chr(48 + M)); end else begin PByteArray(Pointer(Result))[3] := Ord('1'); PByteArray(Pointer(Result))[4] := Byte(Chr(38 + M)); end; end; |
Mit Delphi 7 auf meinem AMD sehe ich keinen Geschwindigkeitsunterschied zum ASM Code.
Edit: \\
In Assembler sieht's dann so aus:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107:
| function ConvertDate(const ADate: AnsiString): AnsiString; asm push ebx push esi mov ebx, edx mov esi, eax mov eax, ebx mov edx, $00000008 call System.@LStrSetLength mov edx, esi mov cx, [edx] mov eax, [ebx] mov [eax], cx mov cl, [edx+$07] mov [eax+$06], cl mov dl, [edx+$08] mov [eax+$07], dl mov byte ptr [eax+$02], $2E mov byte ptr [eax+$05], $2E mov edx, esi add edx, $03 mov ecx, [edx] cmp ecx, $2D6E614A jnz @1 mov edx, $00000001 jmp @12
@1: cmp ecx, $2D626546 jnz @2 mov edx, $00000002 jmp @12
@2: cmp ecx, $2D72614D jnz @3 mov edx, $00000003 jmp @12
@3: cmp ecx, $2D727041 jnz @4 mov edx, $00000004 jmp @12
@4: cmp ecx, $2D79614D jnz @5 mov edx, $00000005 jmp @12
@5: cmp ecx, $2D6E754A jnz @6 mov edx, $00000006 jmp @12
@6: cmp ecx, $2D6C754A jnz @7 mov edx, $00000007 jmp @12
@7: cmp ecx, $2D677541 jnz @8 mov edx, $00000008 jmp @12
@8: cmp ecx, $2D706553 jnz @9 mov edx, $00000009 jmp @12
@9: cmp ecx, $2D74634F jnz @10 mov edx, $0000000A jmp @12
@10: cmp ecx, $2D766F4E jnz @11 mov edx, $0000000B jmp @12
@11: mov edx, $0000000C
@12: cmp edx, $0A jnl @13 mov byte ptr [eax+$03], $30 add edx, $30 mov [eax+$04], dl pop esi pop ebx ret
@13: mov byte ptr [eax+$03], $31 add edx, $26 mov [eax+$04], dl pop esi pop ebx end; |
_________________ Ciao, Sprint.
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Do 18.08.05 19:03
Meine Motivation lag in diesem Beitrag, dass ich mit der Pascal Syntax den Delphi Compiler dazu bewege, den selben Assembler Code zu erstellen wie es retnyg von Hand geschrieben hat. Das ist mir auch fast geglückt.
Naja, nun weiß ich wenigsten wo man die Case Anweisung in Records sinnvoll einsetzen kann.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43:
| function ConvertDate(const ADate: AnsiString): AnsiString; type PConvType = ^TConvType; TConvType = packed record case Byte of 0: (A: Cardinal; B: Cardinal;); 1: (C: array[0..4] of Byte; D: Cardinal;); 2: (E: array[0..2] of Byte; F: Cardinal;); 3: (G: Word; H: Cardinal;); end; begin SetLength(Result, 8); PConvType(Pointer(Result)).A := PConvType(Pointer(ADate)).A; PConvType(Pointer(Result)).B := PConvType(Pointer(ADate)).D; if PConvType(Pointer(ADate)).F = Byte('J') or Byte('a') shl 8 or Byte('n') shl 16 or Byte('-') shl 24 then PConvType(Pointer(Result)).H := Byte('.') or Byte('0') shl 8 or Byte('1') shl 16 or Byte('.') shl 24 else if PConvType(Pointer(ADate)).F = Byte('F') or Byte('e') shl 8 or Byte('b') shl 16 or Byte('-') shl 24 then PConvType(Pointer(Result)).H := Byte('.') or Byte('0') shl 8 or Byte('2') shl 16 or Byte('.') shl 24 else if PConvType(Pointer(ADate)).F = Byte('M') or Byte('a') shl 8 or Byte('r') shl 16 or Byte('-') shl 24 then PConvType(Pointer(Result)).H := Byte('.') or Byte('0') shl 8 or Byte('3') shl 16 or Byte('.') shl 24 else if PConvType(Pointer(ADate)).F = Byte('A') or Byte('p') shl 8 or Byte('r') shl 16 or Byte('-') shl 24 then PConvType(Pointer(Result)).H := Byte('.') or Byte('0') shl 8 or Byte('4') shl 16 or Byte('.') shl 24 else if PConvType(Pointer(ADate)).F = Byte('M') or Byte('a') shl 8 or Byte('y') shl 16 or Byte('-') shl 24 then PConvType(Pointer(Result)).H := Byte('.') or Byte('0') shl 8 or Byte('5') shl 16 or Byte('.') shl 24 else if PConvType(Pointer(ADate)).F = Byte('J') or Byte('u') shl 8 or Byte('n') shl 16 or Byte('-') shl 24 then PConvType(Pointer(Result)).H := Byte('.') or Byte('0') shl 8 or Byte('6') shl 16 or Byte('.') shl 24 else if PConvType(Pointer(ADate)).F = Byte('J') or Byte('u') shl 8 or Byte('l') shl 16 or Byte('-') shl 24 then PConvType(Pointer(Result)).H := Byte('.') or Byte('0') shl 8 or Byte('7') shl 16 or Byte('.') shl 24 else if PConvType(Pointer(ADate)).F = Byte('A') or Byte('u') shl 8 or Byte('g') shl 16 or Byte('-') shl 24 then PConvType(Pointer(Result)).H := Byte('.') or Byte('0') shl 8 or Byte('8') shl 16 or Byte('.') shl 24 else if PConvType(Pointer(ADate)).F = Byte('S') or Byte('e') shl 8 or Byte('p') shl 16 or Byte('-') shl 24 then PConvType(Pointer(Result)).H := Byte('.') or Byte('0') shl 8 or Byte('9') shl 16 or Byte('.') shl 24 else if PConvType(Pointer(ADate)).F = Byte('O') or Byte('c') shl 8 or Byte('t') shl 16 or Byte('-') shl 24 then PConvType(Pointer(Result)).H := Byte('.') or Byte('1') shl 8 or Byte('0') shl 16 or Byte('.') shl 24 else if PConvType(Pointer(ADate)).F = Byte('N') or Byte('o') shl 8 or Byte('v') shl 16 or Byte('-') shl 24 then PConvType(Pointer(Result)).H := Byte('.') or Byte('1') shl 8 or Byte('1') shl 16 or Byte('.') shl 24 else PConvType(Pointer(Result)).H := Byte('.') or Byte('1') shl 8 or Byte('2') shl 16 or Byte('.') shl 24 end; |
_________________ Ciao, Sprint.
|
|
retnyg
      
Beiträge: 2754
SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
|
Verfasst: Do 18.08.05 21:18
Sprint hat folgendes geschrieben: | Meine Motivation lag in diesem Beitrag, dass ich mit der Pascal Syntax den Delphi Compiler dazu bewege, den selben Assembler Code zu erstellen wie es retnyg von Hand geschrieben hat. Das ist mir auch fast geglückt. |
in der tat ^^
Sprint hat folgendes geschrieben: | Naja, nun weiß ich wenigsten wo man die Case Anweisung in Records sinnvoll einsetzen kann.  |
verdammt gute idee mit dem case trick, der code ist nun auch schneller.
da hat der compiler wohl noch eine anweisung rausoptimiert.
er funktioniert aber leider nur wenn das datum mit '-' getrennt wurde (bei meinem ist es egal, und er nimmt das eingangstrennzeichen auch fürs result)
_________________ es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
|
|
|