Registriert seit: 22. Jul 2004
Ort: Münster Osnabrück
116 Beiträge
|
AW: Schnittmenge von mehreren Mengen ermitteln
21. Mär 2012, 07:28
Hallo,
Ach Herr je,
da will man clever sein und fällt wieder auf die Nase
Weil bei mir PrepareSamples wegen random in freepascal so ewig dauerte, kam ich auf die Idee, für eine neue Runde Left aus Right zu kopieren und anschliessend nur PrepareSamples(Right) aufzurufen.
Dämlicherweise habe ich dies nicht ans Ende der repetitions-Schleife getan sondern noch in der Schleife für die Varianten.
Deshalb hatten die Nicht-Ersten Varianten immer gleiche Felder zu untersuchen, was rasend schnell ist.
Dies habe ich nun geändert.
@Amateurprofi:
Ich benutze seit der letzten Version für die Belegung der Testfelder die Version von Panthrax.
Ich weiß nicht, ob freepascal statt length, high abspeichert und deshalb das Programm das letzte Element des array nicht mehr testet
Delphi-Quellcode:
asm
...
mov edi,[eax] // @Intersect[0]
// Zeiger in Intersect und Data hinter jeweils letzten Eintrag
// stellen und Indizes auf jeweils ersten Eintrag ausrichten
lea edi,[edi+ecx*8] // @Intersect[Len] // Offset berechnen damit
neg ecx // [edi+ecx*8] = Intersect[0]
..
mov esi,[edx] // @Data[0]
..
mov ebx,[esi-4] // Length(Data) oder High(Data)?
...
add ecx,1 // Nächster Intersect-Index
je @SetRes // Fertig
end;
Deshalb hab ich die Vorbelegung derart geändert, das im letzten Element im High(TData) steht.
Delphi-Quellcode:
procedure PrepareSamples(out Value: TSampleArray; const N: NativeInt = 10000000; const S: NativeInt = 5);
var
I: NativeInt;
begin
SetLength(Value, N);
Value[0] := Random(S);
for I := 1 to N - 2 do
Value[I] := Value[I - 1] + Random(S) + 1;
Value[N-1] := High(TData);
end;
Dann habe ich die Ausgabe wie im Kommentar von Panthrax gemacht, also die Ausgabe von Länge der Schnittmenge und Laufzeit,aber mit Komma getrennt ( csv )
Mit Freepascal ergibt sich:
Code:
#39, Pascal 10000000
#51, Pascal 10000000
#61, Pascal 10000000
#59, Assem 9999999
Messung #39, Pascal #51, Pascal #61, Pascal #59, Assem
1,3332223,125 ,3332223,116 ,3332223,111 ,3332222,76
2,3333764,129 ,3333764,121 ,3333764,118 ,3333763,70
3,3338301,123 ,3338301,117 ,3338301,112 ,3338300,69
4,3334825,123 ,3334825,115 ,3334825,111 ,3334824,68
5,3330696,123 ,3330696,115 ,3330696,112 ,3330695,68
6,3333988,124 ,3333988,119 ,3333988,111 ,3333987,71
7,3333174,123 ,3333174,117 ,3333174,111 ,3333173,76
8,3333983,123 ,3333983,118 ,3333983,111 ,3333982,68
9,3335054,125 ,3335054,117 ,3335054,112 ,3335053,74
10,3333229,123 ,3333229,117 ,3333229,111 ,3333228,71
11,3332975,123 ,3332975,115 ,3332975,111 ,3332974,70
Fertig.
Hier hat die Assembler Version immer ein Element zu wenig.
Gruß Horst
EDIT:
Der Test mit Freepascal ergab:
Delphi-Quellcode:
L := @Left[0];
R := @Right[0];
DEC(R); writeln(R^);INC(R);
DEC(L); writeln(L^);INC(L);
...
Ausgabe
9999999
9999999
Also speichert freepascal High(DynArray) statt Length(DynArray)
Böse Falle das!
Geändert von Horst_ (21. Mär 2012 um 07:40 Uhr)
Grund: Freepascal getestet
|