Autor Beitrag
kamikaze
Hält's aus hier
Beiträge: 14

WIN XP pro
D6 enterprise
BeitragVerfasst: Sa 24.09.05 21:31 
hab ne sequenz wo ich die Zeit berechne, in ein array speichere und dann den durchschnitt bilde...

ausblenden volle Höhe 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:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 14

WIN XP pro
D6 enterprise
BeitragVerfasst: 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



BeitragVerfasst: 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 Suche im MSDN GETTHREADTIMES.


Zuletzt bearbeitet von Luckie am Mo 26.09.05 13:15, insgesamt 1-mal bearbeitet
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8549
Erhaltene Danke: 478

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 14

WIN XP pro
D6 enterprise
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 14

WIN XP pro
D6 enterprise
BeitragVerfasst: Mi 28.09.05 22:25 
Hab den Übeltäter gefunden:

ausblenden 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:

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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)
ausblenden volle Höhe 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:
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..15of String[7];
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure ByteToBin(const Value: String; range: integer;var outStr: String);
  public
    { Public-Deklarationen }
  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));//'U'=01010101
//  self.Memo1.Lines.Add(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)]));
//  self.Memo1.Lines.Add(strErgebnis);
end;

end.


Gruss Horst
kamikaze Threadstarter
Hält's aus hier
Beiträge: 14

WIN XP pro
D6 enterprise
BeitragVerfasst: 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:

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
tChar   = ^Char;//Bei pChar hat er immer das Zeichen und nicht die Adresse uebergeben
...
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