Autor |
Beitrag |
kamikaze
Hält's aus hier
Beiträge: 14
WIN XP pro
D6 enterprise
|
Verfasst: Sa 24.09.05 21:31
hab ne sequenz wo ich die Zeit berechne, in ein array speichere und dann den durchschnitt bilde...
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:
| var start,stop,i,j,anz: Integer; S, str: String; fs: Tfilestream; b: array of Byte; arr: TBits; Zeit: array of Integer;
... repeat start := Gettickcount; S := str; for i := 0 to 32767 do begin fs.Read(b[i], SizeOf(byte)); S := S + BytetoBin(b[i]); end; for i := 0 to (length(S) div anz) - 1 do arr[BintoDec(PChar(COPY(S,i*anz+1,anz)))] := true; str := COPY(S,length(S) - (length(S) - (length(S) div anz)*anz)+1,length(S) - (length(S) div anz)*anz); stop := Gettickcount; Zeit[j] := stop-start; Inc(j); until fs.Size = fs.Position; ...
function TForm1.ByteToBin(Value: Byte): String; Var B: PByte; Begin Value := Value And $FF; Result := StringOfChar('0', 8); B := @Byte(Result[8]); While Value <> 0 Do Begin Inc(B^, Value And 1); Value := Value Shr 1; Dec(B); End; End;
function TForm1.BintoDec(Value: PChar): Integer; begin Result := 0; while Value^ <> #0 do begin Result := Result shl 1; Result := Result or Ord(Value^ = '1'); Inc(Value); end; end;
for i := 0 to high(Zeit) do j := j + Zeit[i]; ListBox1.Items.Add(FloattoStr(j/high(Zeit))); |
dabei erhalte ich bei der gleichen Datei als Durchschnittszeiten zwischen 52 und 3190 Millisekunden, das ist ein extremer Unterschied, woran kann der liegen??
_________________ manchmal sind die Antworten die wir suchen einfacher als man denkt
|
|
uall@ogc
      
Beiträge: 1826
Erhaltene Danke: 11
Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
|
Verfasst: So 25.09.05 14:34
hi startest du das programm zwischendruch neu? oder läßt du das einmal durchalufen wo es lange dauert und bei jedem weiteren durchlauf (ohen programm beenden) gehst schneller
das liegt dann vielleicht daran das du nen string immer vergrößerst, beim 2. mal durchlaufen hat delphi dann schon einen großen speicehrbereich frei für den string, dann muss kein neuer speicher allociert werden
oder windows hat die datei die du einließt noch irgendwie im speicher etc. 
_________________ wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
|
|
GTA-Place
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: So 25.09.05 14:43
Da du J nicht zurückstetzt (außer du startest dazwischen neu), wird die Zahl größer.
Zuerst bekommst du 59 / high();, dann 590 / high();, dann 5900 / high();, ...;
_________________ "Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
Zuletzt bearbeitet von GTA-Place am So 25.09.05 14:48, insgesamt 1-mal bearbeitet
|
|
uall@ogc
      
Beiträge: 1826
Erhaltene Danke: 11
Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
|
Verfasst: So 25.09.05 14:47
hatte den quelltext nicht getestet, aber sowas sollte man doch merken wenn die zeit um einen bestimmten faktor ansteigt und nich wie von dir gesagt schwangt.
_________________ wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
|
|
kamikaze 
Hält's aus hier
Beiträge: 14
WIN XP pro
D6 enterprise
|
Verfasst: Mo 26.09.05 12:50
j wird am anfang immer nochma neu gesetzt, hatte ich aus Versehen weggelassen.
kann sein, dass es schneller wird, wenn man es öffter macht ohne es neu zu starten, aber trotzdem kommen zwischendurch immer wieder hohe werte.
So war meine Durchschnittszeiten bei einer Datei:
3192
74
2078
620
403
52
52
768
1304
Hab zwischendurch nicht neu gestartet.
hab mir auch ma die Zeiten für die einzelnen Durchläufe angeguckt, da schwankts sogar von 50 bis 17000 Msek.
_________________ manchmal sind die Antworten die wir suchen einfacher als man denkt
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 26.09.05 12:59
Was laufen noch für Programme im Hintergrund? Desweiteren ist GetTickCount sehr, sehr ungenau und dafür eigentlich nicht zu gebrauchen, da es auch die Zeit mit mißt, die dein Thread nicht aktiv ist und daraufwartet wieder CPU Zeit zugeteilt zu bekommen. Wenn dazwischen jetzt andere Threads mit gleicher Priorität liegen, dann kann es schon mal etwas dauern bis er wieder CPU Zeit zugewiesen bekommt. Besser wäre auf alle Fälle GETTHREADTIMES.
Zuletzt bearbeitet von Luckie am Mo 26.09.05 13:15, insgesamt 1-mal bearbeitet
|
|
Gausi
      
Beiträge: 8549
Erhaltene Danke: 478
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mo 26.09.05 13:07
Ein weiterer Punkt dürfte der Platten-Cache sein, oder? Wenn du ne kleine Datei öffnest, und dann Byteweise die Zeichen einliest, braucht das wesentlich mehr Zeit, wenn die Datei echt gelesen wird, als wenn sie noch im Cache liegt.
_________________ We are, we were and will not be.
|
|
kamikaze 
Hält's aus hier
Beiträge: 14
WIN XP pro
D6 enterprise
|
Verfasst: Mi 28.09.05 14:18
Das Problem liegt nich in der Zeitmessung, sondern, dass es mal <10 sek und mal > 5 min braucht um meine Testdatei (ca. 2,82 MB) einzulesen, die Zeitmessung ist nur zur Veanschaulichung.
Keine Ahnung ob das am plattencache liegt, wenns daran liegt, wie kann man dafür sorgen, dass es immer möglichst schnell geht, oder die datei am Anfang im cache ist?
_________________ manchmal sind die Antworten die wir suchen einfacher als man denkt
|
|
kamikaze 
Hält's aus hier
Beiträge: 14
WIN XP pro
D6 enterprise
|
Verfasst: Mi 28.09.05 22:25
Hab den Übeltäter gefunden:
Delphi-Quelltext 1: 2: 3: 4: 5:
| for i := 0 to 32767 do begin fs.Read(b[i], SizeOf(byte)); S := S + BytetoBin(b[i]); end; |
habs modifiziert:
Delphi-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:
| fs.Read(b[1], 32768); S := S + BytetoBin(b,32768);
function TForm1.ByteToBin(Value: String; range: integer): String; Var B: PByte; i: Integer; st: String; c: ^byte; Begin Result := ''; c := @Byte(Value[1]); for i := 1 to range do begin st := StringOfChar('0', 8); B := @Byte(st[8]); While c^ <> 0 Do Begin Inc(B^, c^ And 1); c^ := c^ Shr 1; Dec(B); End; Result := Result + st; c := pointer(cardinal(c)+1); end; End; |
läuft schon wesentlich stabiler, aber nach mehrmaliger Ausführung mit derselben Datei werden die Zeiten wieder groß, keine Ahnung warum, naja vielleicht klärt sich das noch irgendwann...
_________________ manchmal sind die Antworten die wir suchen einfacher als man denkt
|
|
uall@ogc
      
Beiträge: 1826
Erhaltene Danke: 11
Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
|
Verfasst: Do 29.09.05 10:22
für nen
String := String+ "irgendwas"
wird immer neuer speicher allociert, am besten berechnest du vorher wieviel du brauchst
_________________ wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Do 29.09.05 10:30
Hallo,
hast Du Dir schon mal die Speicherauslastung Deines Programms waehrend der Ausfuehrung angesehen?
Funktionen,die eine String als Rueckgabewert haben, sind bei Dauereinsatz immer Speicherfresser, da dieser String nicht aus dem Speicher verschwindet.
Wie dem auch sei ich habe ein anderes Problem bei mir festgestellt. Die Zuweisung eines riesigen Strings in ein MemoFeld mit Wordwrap = true ist der GAU.
Also die 2.8 MB sind nach Minuten erst erschienen(98% CPU).
Ein Vorschlag von mir.Einsatz einer Prozedur mit var Parameter und Benutzung von setlength, wenn die Laenge des endgueltigen Strings bekannt ist.
DIe Laufzeit auf meinem Rechner 0.36 Sekunden ( bei string[4] 0.4 s)
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:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type Tnibble = array[0..15] of String[7]; TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); private procedure ByteToBin(const Value: String; range: integer;var outStr: String); public end;
var Form1: TForm1;
implementation {$R *.dfm}
procedure TForm1.ByteToBin(const Value: String; range: integer;var outStr: String); const nibble : Tnibble = ('0000','0001','0010','0011', '0100','0101','0110','0111', '1000','1001','1010','1011', '1100','1101','1110','1111');
Var t0,t1: cardinal; i: Integer; PosOut,c : ^byte; Begin self.Memo1.Lines.Add('Jetzt geht''''s los '); t0 := Gettickcount; setLength(outStr,8*range); Posout := Addr(outStr[1]); c := Addr(Value[1]); for i := 1 to range do begin move(nibble[c^ shr 4][1],PosOut^,4); inc(PosOut,4); move(nibble[c^ AND 15][1],PosOut^,4); inc(PosOut,4); inc(c); end; t1 := Gettickcount; self.Memo1.Lines.Add('Fertig '); self.Memo1.Lines.Add(Format(' %7.4f Sekunden',[(t1-t0)/1000])); End;
procedure TForm1.Button1Click(Sender: TObject); var i : integer; strTest, strErgebnis : String; begin memo1.WordWrap := false; setlength(strTest,2820000); strTest:= StringOfChar(chr(64+16+4+1),length(strTest)); self.Memo1.Lines.Add(Format(' Anzahl Zeichen Eingabe %6d',[length(strTest)]));
self.ByteToBin(strTest,length(strTest),strErgebnis);
self.Memo1.Lines.Add(Format(' Anzahl Zeichen Ergebnis %6d',[length(strErgebnis)])); end;
end. |
Gruss Horst
|
|
kamikaze 
Hält's aus hier
Beiträge: 14
WIN XP pro
D6 enterprise
|
Verfasst: Do 29.09.05 14:23
Danke, die Variante ist wirklich extrem gut!
vielleicht wisst ihr noch was, wie ich diesen Teil noch bissl verbessern kann:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| for i := 0 to (length(S) div anz) - 1 do arr[BintoDec(PChar(COPY(S,i*anz+1,anz)))] := true;
function TForm1.BintoDec(Value: PChar): Integer; begin Result := 0; while Value^ <> #0 do begin Result := Result shl 1; Result := Result or Ord(Value^ = '1'); Inc(Value); end; end; |
die Funktion läuft zwar ganz gut, aber vielleicht kann man noch was verbessern, wegen COPY und so
_________________ manchmal sind die Antworten die wir suchen einfacher als man denkt
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Do 29.09.05 18:25
Hallo,
ich weiss nicht, was Du da vorhast.
Aus einem Binaerstring erzeugst Du die Position in einem BitFeld ??
Durch pChar(COPY(strErgebnis,i*anz+1,anz)) erzeugst Du unnoetige Kopien, wenn Du Dir sicher sein kannst nicht ueber das Ende hinaus zu lesen.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| tChar = ^Char;... anz := 32;
for i := 0 to (length(StrErgebnis) div anz) - 1 do j:=BintoDec(Addr(StrErgebnis[i*anz+1]),anz);
function TForm1.BintoDec(Value : tChar;Anz: cardinal): Integer; begin Result := 0; Anz := cardinal(Value)+Anz; while cardinal(Value) < Anz do begin Result := Result shl 1; Result := Result or Ord(Value^ = '1'); Inc(Value); end; end; |
Anz sollte also maximal 32 sein!
So ist etwa 3.5..4 mal schneller (.2..0.23 Sekunden fuer einen 80 Mbyte strErgebnis statt vorher 0.79..083 Sekunden) uups 400 Mbyte/s haette ich nicht erwartet.
Gruss Horst
|
|
|