Autor Beitrag
ShadowCaster
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 312



BeitragVerfasst: 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.

ausblenden volle Höhe Quelltext
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: 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:

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 312



BeitragVerfasst: 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. :roll:

Hauptsache, man erziehlt den besten Erfolg. :wink:
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: 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. :roll: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 312



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: 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...! :wink:

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
ShadowCaster
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 312



BeitragVerfasst: Mi 26.03.03 14:09 
aber ne Menge dazugelernt hab ich hier in diesem Forum dank euch schon. THX goes to Auq :wink:
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: So 30.03.03 22:10 
mal ne Frage: warum ist While langsammer als eine For schleife ???
das ist mir neu : :shock:

_________________
MFG
Michael Springwald, "kann kein englisch...."
ShadowCaster
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 312



BeitragVerfasst: 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.
:wink:
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 312



BeitragVerfasst: 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 :) :wink:
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: 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...."