| Autor |
Beitrag |
ShadowCaster
      
Beiträge: 312
|
Verfasst: Mi 26.03.03 11:20
Erstmal sorry. Den Link konnte ich nicht mehr auftreiben...  Die Site gibt es wohl nicht mehr.
Motzi, ich kann dir nur recht geben. Memorystream ist in jedem Falle ungeeignet. Ich verwende ihn nurnoch wenns schnell gehen soll oder bei kleinen Dateien (sehr klein), da sonst alles eh wieder auf der Platte (swap) und nicht im Ram landet. Eigentlich müsste Memorystream in MemorySwapStream umbenannt werden.
naja, verwende mal Blockread  Das ist sau schnell.
Hier der AsmCode von Blockread (Blockread in delphi wird nicht aus der WinApi verwendet. Das ist ne eigene Routine). Blockread hat aber einen Nachteil. Wenn du von einer CD auf die Platte liest, ist er minimal langsamer als der Api-Befehl aber auf der Platte bis zu doppelt so schnell.
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:
| ; ******************************************************* ; * * ; * Delphi Runtime Library * ; * * ; * Copyright (c) 1996,98 Inprise Corporation * ; * * ; *******************************************************
INCLUDE SE.ASM INCLUDE FILEIO.ASM
.386 .MODEL FLAT
EXTRN ReadFile:NEAR, GetLastError:NEAR, SetInOutRes:NEAR
PUBLIC _BlockRead
.CODE
; PROCEDURE _BlockRead( f: File; buffer: Pointer; recCnt: Longint; var result: Longint);
_BlockRead PROC
; -> EAX Pointer to file variable ; EDX Pointer to buffer ; ECX Number of records to read ; [ESP+4] Pointer to result or nil
PUSH EBX PUSH ESI
MOV EBX,EAX MOV ESI,EDX
MOV EDX,[EBX].Mode ; File must be open SUB EDX,fmInput CMP EDX,fmInOut-fmInput JA @@fileNotOpen
; ReadFile(f.Handle, buffer, recCnt*f.RecSize, @result, Nil);
PUSH ECX
PUSH 0 ; space for OS result MOV EAX,ESP
PUSH 0 ; pass lpOverlapped PUSH EAX ; pass @result
MOV EAX,[EBX].RecSize MUL ECX PUSH EAX ; pass nNumberOfBytesToRead
PUSH ESI ; pass lpBuffer PUSH [EBX].Handle ; pass hFile CALL ReadFile DEC EAX ; check EAX = TRUE POP EAX ; pop result POP ECX JNZ @@error
XOR EDX,EDX DIV [EBX].RecSize ; recCnt = result DIV f.RecSize MOV EDX,[ESP+4+8] TEST EDX,EDX JE @@noResult MOV [EDX],EAX @@exit: POP ESI POP EBX
RET 4
@@noResult: CMP EAX,ECX JE @@exit MOV EAX,100 JMP @@errExit
@@error: CALL GetLastError @@errExit: CALL SetInOutRes XOR EAX,EAX JMP @@exit
@@fileNotOpen: MOV EAX,103 JMP @@errExit
_BlockRead ENDP
END |
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Mi 26.03.03 12:01
| ShadowCaster hat folgendes geschrieben: | naja, verwende mal Blockread Das ist sau schnell. |
Hab ich, war ungefähr genauso schnell wie ein FileStream!
| Zitat: | | Hier der AsmCode von Blockread (Blockread in delphi wird nicht aus der WinApi verwendet. Das ist ne eigene Routine). Blockread hat aber einen Nachteil. Wenn du von einer CD auf die Platte liest, ist er minimal langsamer als der Api-Befehl aber auf der Platte bis zu doppelt so schnell. |
Doch, im Endeffekt landet immer alles in der API! Debug einen BlockRead-Aufruf mal im CPU-Fenster, du wirst sehen früher oder später landest du bei KERNEL32.ReadFile!
Sieht man ja auch schon im Code:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| EXTRN ReadFile:NEAR <---
{...} ; ReadFile(f.Handle, buffer, recCnt*f.RecSize, @result, Nil);
PUSH ECX
PUSH 0 ; space for OS result MOV EAX,ESP
PUSH 0 ; pass lpOverlapped PUSH EAX ; pass @result
MOV EAX,[EBX].RecSize MUL ECX PUSH EAX ; pass nNumberOfBytesToRead
PUSH ESI ; pass lpBuffer PUSH [EBX].Handle ; pass hFile CALL ReadFile <--- {...} |
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
ShadowCaster
      
Beiträge: 312
|
Verfasst: Mi 26.03.03 12:21
das ist richtig aber das geht über den Kernel und nicht über irgendwelche externen Api-Dll's  Naja Filestream und Blockread müsste eigentlich fast genauso schnell wie AssignFile und Blockread sein. Da hast du recht. Wenn man von den paar extrabefehlen im Filestream absieht, die die CPU abarbeiten muss, müsste er mit blockread gleich schnell sein.
Nur wofür Filestream und blockread wenn ich doch gleich meinen Speicher selbst verwalten kann und kein Filestreamobjekt brauche? Ich mags eigentlich lieber wenn ich sehe, was hinter den Aufrufen im Code steht.
Aber egal.
Hauptsache, man erziehlt den besten Erfolg. 
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Mi 26.03.03 12:37
| ShadowCaster hat folgendes geschrieben: | das ist richtig aber das geht über den Kernel und nicht über irgendwelche externen Api-Dll's |
Ähm.. ich glaub du hast da etwas ein bisschen verdreht.  ReadFile ist eine ganz normale API-Funktion aus der Kernel32.dll, so wie viele andere auch! Link: msdn.microsoft.com/l...io/base/readfile.asp
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
ShadowCaster
      
Beiträge: 312
|
Verfasst: Mi 26.03.03 13:33
ach f.....  auch egal.. .
Jedenfalls glaub ich, dass nach der Diskussion in dem Thread hier bald keine Fragen mehr offen sind zum Thema streams... *LOL*
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Mi 26.03.03 13:43
| ShadowCaster hat folgendes geschrieben: | | Jedenfalls glaub ich, dass nach der Diskussion in dem Thread hier bald keine Fragen mehr offen sind zum Thema streams... *LOL* |
Da hast du allerdings recht...! 
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
ShadowCaster
      
Beiträge: 312
|
Verfasst: Mi 26.03.03 14:09
aber ne Menge dazugelernt hab ich hier in diesem Forum dank euch schon. THX goes to Auq 
|
|
mimi
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: So 30.03.03 22:10
mal ne Frage: warum ist While langsammer als eine For schleife ???
das ist mir neu : 
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
ShadowCaster
      
Beiträge: 312
|
Verfasst: Mo 31.03.03 12:29
hier ein Auszug aus der Delphi-Hilfe:
| Zitat: |
for...to-Anweisung hat starke Ähnlichkeit mit dem folgenden while-Konstrukt:
begin
Zähler := Anfangswert;
while Zähler <= Endwert do
begin
Anweisung;
Zähler := Succ(Zähler);
end;
end
Im Unterschied zur for...to-Anweisung wird Endwert aber in der while-Schleife vor jedem Durchlauf erneut ausgewertet. Wenn Endwert ein komplexer Ausdruck ist, kann dies eine Verlangsamung der Ausführungsgeschwindigkeit zur Folge haben. Außerdem können sich von Anweisung verursachte Änderungen an Endwert auf die Ausführung der Schleife auswirken.
| 
|
|
mimi
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Mo 31.03.03 17:08
wieder mal was neues gelehrnt, ich nutze selten eine weile schleife am liebsten sind mir diese reper(until) schleifen irgenwie- aber egal...
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
ShadowCaster
      
Beiträge: 312
|
Verfasst: Di 01.04.03 08:36
es ist auch eigentlich egal  wenn du die Whileschleife dazu benutzt, um die Blöcke der Datei einzulesen oder repeat-until und die For-Schleife für die Blöcke durchzugehen, kann nichts schief gehen 
|
|
mimi
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Di 01.04.03 17:56
Doch es kann vieles schief gehen z.b. das man vergies eine Break anweisung einzusetztne in einer While schleife
naja egal...
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|