Autor Beitrag
molendrotter
Hält's aus hier
Beiträge: 10

Win XP
D4 Pers, D6 Prof, D7 Entp
BeitragVerfasst: Fr 12.08.05 19:40 
hi will einen speziellen String in Tdate format umwandeln:
Der string sieht so aus: '01-Aug-05' also dd-Mmm-yyyy wobei die Monate immer so aussehen: Jan Feb....

ich könnte den String mit StringReplace und if abfragen bestimmt in '01-08-05' umwandeln und dann das machen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var
  FormatSettings: TFormatSettings;
  date: Tdate;
  s: string;
begin
    s:= '01-01-05';
    FormatSettings.DateSeparator:= '-';
    FormatSettings.ShortDateFormat:= 'd/m/y';
    date := strtodate(s, FormatSettings);
    showmessage(datetostr(date));
end;


aber weil das zu langsam ist muss es direkt gehen, also hab ich mal das probiert:

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:
var
  FormatSettings: TFormatSettings;
  date: Tdate;
  s: string;
begin
    s:= '01-Aug-05';
    FormatSettings.DateSeparator:= '-';
    FormatSettings.ShortDateFormat:= 'd/m/y';
    Formatsettings.ShortMonthNames[1] := 'Jan';
    Formatsettings.ShortMonthNames[2] := 'Feb';
    Formatsettings.ShortMonthNames[3] := 'Mar';
    Formatsettings.ShortMonthNames[4] := 'Apr';
    Formatsettings.ShortMonthNames[5] := 'May';
    Formatsettings.ShortMonthNames[6] := 'Jun';
    Formatsettings.ShortMonthNames[7] := 'Jul';
    Formatsettings.ShortMonthNames[8] := 'Aug';
    Formatsettings.ShortMonthNames[9] := 'Sep';
    Formatsettings.ShortMonthNames[10] := 'Oct';
    Formatsettings.ShortMonthNames[11] := 'Nov';
    Formatsettings.ShortMonthNames[12] := 'Dec'
    date := strtodate(s, FormatSettings);
    showmessage(datetostr(date));
end;


es kommt aber der Fehler: '01-Aug-05' is not a valid date

PS:
weiss einer wie ich '01-Aug-05' effizient in '01-08-05' umwandeln kann mit stringreplace oder so

ausblenden Delphi-Quelltext
1:
2:
s:= '01-Aug-05';
    stringreplace(s,'Aug','08',[rfReplaceAll, rfIgnoreCase]);


klappt nämlich ned??????? oder was mach ich falsch????

soll ich des alles mit pos delete insert machen oder wie????? wär ja voll lam das zeug!!!

Moderiert von user profile iconAXMD: Code- durch Delphi-Tags ersetzt.


Zuletzt bearbeitet von molendrotter am Mo 15.08.05 11:08, insgesamt 2-mal bearbeitet
StefanH
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1144

Win XP
D5 Standard, D7 Pers, D2005 Pers
BeitragVerfasst: Fr 12.08.05 20:49 
user profile iconmolendrotter hat folgendes geschrieben:
ausblenden Quelltext
1:
2:
s:= '01-Aug-05';
s:= stringreplace(s, 'Aug', '08', [rfReplaceAll, rfIgnoreCase]);


klappt nämlich ned??????? oder was mach ich falsch????


Ich denke, 2 Fragezeichen würden reichen, aber egal :roll: StringReplace ist eine Funktion.

_________________
"Als es noch keine Computer gab, war das Programmieren noch relativ einfach."(Edsger W. Dijkstra)
"Ich bin nicht von Sinnen, sondern ich rede wahre und vernünftige Worte." (Paulus)
Rolf_Geisler
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 16

WIN XP
D7 Prof
BeitragVerfasst: Fr 12.08.05 20:52 
Hallo,
für das, was Du vorhast, gibt es die Funktion StrToDate. Dort kannst Du über die FormatSettings auch die Monatsnamen und das Trennzeichen festlegen.
Schau mal in der Online-Hilfe nach.
Rolf
Rolf_Geisler
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 16

WIN XP
D7 Prof
BeitragVerfasst: Sa 13.08.05 09:58 
Sorry, bin ein wenig zerstreut. StrToDate verwendest Du ja schon. Aber vielleicht musst Du am ShortDateFormat etwas herumspielen. Könnte mir vorstellen, dass anstelle des Slash der (schon einmal definierten) Datumstrenner stehen muss. Win ist bei solchen Kleinigkeiten manchmal etwas eigen ... Habe da schon Merkwürdiges erlebt
Rolf
molendrotter Threadstarter
Hält's aus hier
Beiträge: 10

Win XP
D4 Pers, D6 Prof, D7 Entp
BeitragVerfasst: Sa 13.08.05 17:43 
@stefanh
danke hat gut funktioniert, das ich das nicht gleich gesehen hab(-: is ja klar, die function gibt den string ja aus


@Rolf geißler
Zitat:

Aber vielleicht musst Du am ShortDateFormat etwas herumspielen. Könnte mir vorstellen, dass anstelle des Slash der (schon einmal definierten) Datumstrenner stehen muss.

also so meinst du?:
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:
var
  FormatSettings: TFormatSettings;
  date: Tdate;
  s: string;
begin
    s:= '01-Aug-05';
    FormatSettings.DateSeparator:= '-';
    FormatSettings.ShortDateFormat:= 'd-m-y';
    Formatsettings.ShortMonthNames[1] := 'Jan';
    Formatsettings.ShortMonthNames[2] := 'Feb';
    Formatsettings.ShortMonthNames[3] := 'Mar';
    Formatsettings.ShortMonthNames[4] := 'Apr';
    Formatsettings.ShortMonthNames[5] := 'May';
    Formatsettings.ShortMonthNames[6] := 'Jun';
    Formatsettings.ShortMonthNames[7] := 'Jul';
    Formatsettings.ShortMonthNames[8] := 'Aug';
    Formatsettings.ShortMonthNames[9] := 'Sep';
    Formatsettings.ShortMonthNames[10] := 'Okt';
    Formatsettings.ShortMonthNames[11] := 'Nov';
    Formatsettings.ShortMonthNames[12] := 'Dez';
    date := strtodate(s, FormatSettings);
    showmessage(datetostr(date));
end;


nee macht kein unterschied, hab ich schon probiert, haut ned hin, wo liegt nur mein fehler?
longdateformat und longmonthnames klappt au ned.
das gibts doch ned, is is ja zum verzweifeln.

Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt.
AXMD
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: Sa 13.08.05 17:51 
Sollte ShortDateFormat nicht 'dd-mmm-yy' sein?

AXMD
StefanH
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1144

Win XP
D5 Standard, D7 Pers, D2005 Pers
BeitragVerfasst: Sa 13.08.05 17:54 
user profile iconAXMD hat folgendes geschrieben:
Sollte ShortDateFormat nicht 'dd-mmm-yy' sein?


hab ich mir grad auch gedacht. funktioniert bloß nicht. komisch :roll:

_________________
"Als es noch keine Computer gab, war das Programmieren noch relativ einfach."(Edsger W. Dijkstra)
"Ich bin nicht von Sinnen, sondern ich rede wahre und vernünftige Worte." (Paulus)
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Sa 13.08.05 18:14 
Was hält Dich davon ab, es so zu machen? Ist doch kompakt...
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
Function ConvertDate (Const aDate : String) : String;
Const
  szMonths = 'JanFebMarAprMayJunJulAugSepOctNovDec';

Begin
  Result := Format('%s.%s.%s',[Copy (aDate,1,2),
    FormatFloat ('00',(Pos (Copy (aDate,4,3),szMonths) + 2div 3),
    Copy (aDate,8,2)])
End;

Und wenn Dir das Pos zu lahm sein sollte (wobei ich mich frage, in was für einer Applikation sowas eine Rolle spielt), dann baue Dir einen kleinen DEA, der die Monatsnamen in Monatsnummern überführt und scanne das Datum von links nach rechts. Schneller bekommt man das dann nämlich garantiert nicht hin. Das geht natürlich in Assembler noch viel schneller.

Woher kommen die Daten denn?
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 13.08.05 19:21 
Also so geht es:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm1.Button1Click(Sender: TObject);
var
  MyDate                 : TDate;
  s                      : string;
begin
  s := '3-8-05';
  ShortDateFormat := 'dd-mmm-y';
  MyDate := StrToDate(s);
  ShowMessage(DateToStr(MyDate));
end;

Das Problem ist, im Datumsstring dürfen nur Zahlen vorkommen.

@alzaimar:
Also das mit deiner Stringkonstanten und dem copy ist ja wohl das schlechteste, was einem einfallen kann. Unperformanter geht es kaum noch. warum nimmst du nicht ein zwölf elementiges Array?
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Sa 13.08.05 21:04 
Hi Luckie.
Also, ich krieg das noch viel viel unperformanter hin, kein Problem. :D
Ein Array mit 12 Einträgen ist aber auch nicht viel schneller. Wenn schon, dann (wie ich ja schon erwähnte), ein DEA oder ein Dictionary, aber das ist angesichts der 36 Zeichen, die zu durchsuchen sind, sowieso eine kindische Überlegung, was denn hier nun der schnellste Algorithmus ist, ehrlich. Nächstes Mal solltest Du erst nachdenken (und lesen), und erst dann kritisieren. Aber Du schiesst gerne schnell, das ist schon ok.

Und wenn Du meine Bemerkung gelesen hast, dann ging es ums Kompakte (ich fands lustig, das Ganze in eine Zeile zu quetschen) und die Frage, wieso man sich überhaupt Gedanken über die Performance macht. Desweiteren hatte ich schon den DEA erwähnt, der dann das optimale Mittel ist, um in einem Durchgang sowohl Tag, als auch Monat und Jahr zu konvertieren. Und DAS ist dann schnell. Schlag Dir das mit dem Array lieber aus dem Kopf.
Sprint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 849



BeitragVerfasst: Sa 13.08.05 21:40 
user profile iconLuckie hat folgendes geschrieben:
Also das mit deiner Stringkonstanten und dem copy ist ja wohl das schlechteste, was einem einfallen kann. Unperformanter geht es kaum noch. warum nimmst du nicht ein zwölf elementiges Array?

*lol*

Vielleicht solltest du dich mal mit Delphi beschäftigen.

_________________
Ciao, Sprint.
molendrotter Threadstarter
Hält's aus hier
Beiträge: 10

Win XP
D4 Pers, D6 Prof, D7 Entp
BeitragVerfasst: So 14.08.05 04:00 
@alzheimer
Zitat:

Und wenn Dir das Pos zu lahm sein sollte (wobei ich mich frage, in was für einer Applikation sowas eine Rolle spielt)


wenn man 6,3GB Daten verarbeiten will spielt das eine sehhhhhhhher große rolle, zumal werden die Daten alle 1,5 Stunden neu angelegt, mehr als 2,5 Stunden darf es nicht dauern. Soviel zur performance, also die function wird milliardenmal aufgerufen(habs aber nicht gezählt) und bald wird es mehr und mehr...... und der PC wird nicht schneller!!!

zuerst hab ich suchen und ersetzten so geregelt:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure strrepl(subo, subn: Stringvar s: String);
var
  i:integer;
begin
    repeat
    i:= posex(subo,s,i);
    if i<> 0 then begin
      delete(s,i,length(subo));
      insert(subn,s,i);
    end;
    until posex(subo,s,i) = 0;
end;

total lahm...............
dann hab ich die Monate wie 'Aug' mit:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
strrepl('Jan','01' ,s);
strrepl('Feb','02' ,s);
strrepl('Mar','03' ,s);
strrepl('Apr','04' ,s);
strrepl('May','05' ,s);
strrepl('Jun','06' ,s);
strrepl('Jul','07' ,s);
strrepl('Aug','08' ,s);
strrepl('Sep','09' ,s);
strrepl('Oct','10' ,s);
strrepl('Nov','11' ,s);
strrepl('Dec','12' ,s);

ersetzt bis ich verstanden hab wie das mit den Stringreplace Funktioniert:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
s:= stringreplace(s, 'Jan','01',[rfReplaceAll , rfIgnoreCase]);
s:= stringreplace(s, 'Feb','02',[rfReplaceAll , rfIgnoreCase]);
s:= stringreplace(s, 'Mar','03',[rfReplaceAll , rfIgnoreCase]);
s:= stringreplace(s, 'Apr','04',[rfReplaceAll , rfIgnoreCase]);
s:= stringreplace(s, 'May','05',[rfReplaceAll , rfIgnoreCase]);
s:= stringreplace(s, 'Jun','06',[rfReplaceAll , rfIgnoreCase]);
s:= stringreplace(s, 'Jul','07',[rfReplaceAll , rfIgnoreCase]);
s:= stringreplace(s, 'Aug','08',[rfReplaceAll , rfIgnoreCase]);
s:= stringreplace(s, 'Sep','09',[rfReplaceAll , rfIgnoreCase]);
s:= stringreplace(s, 'Oct','10',[rfReplaceAll , rfIgnoreCase]);
s:= stringreplace(s, 'Nov','11',[rfReplaceAll , rfIgnoreCase]);
s:= stringreplace(s, 'Dec','12',[rfReplaceAll , rfIgnoreCase]);


dann konnte ich wie gewohnt den String in ein Datum umwandeln, aber noch zu lahm und mit assembler kenn ich mich zu wenig aus als das ich sowas kompliziertes erstellen könnte.

und @luckie

das wusste ich auch schon von anfang an, dass es geht wenn man es nur mit zahlen macht, ich hab nur en problem damit den String in Zahlen umzuwanden und damit notwendige Performance zu verlieren, wenn es auch schneller und direk, quasi optimiert funktioniert.





wär toll wenn einer zeigt wie ich das vielleicht mit assembler lösen könnte(is ne 32bit Anwendung)




PS: performance ist zeitgewinn, zeit ist geld, mehr zeit ist mehr geld, und geld ist vergnügen, vergnügen ist programieren, programmieren ist performance....

Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt.
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: So 14.08.05 04:50 
luckie's idee mit dem array ist nicht so schlecht, immerhin 30 % schneller als das dauernde pos und copy.
auf alzaimar's code abgemünzt sähe das so aus:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
Function ConvertDate (Const aDate : String) : String;
Const
  szMonths : array [1..12of string[3] = ('Jan''Feb''Mar''Apr''May''Jun''Jul''Aug' , 'Sep''Oct''Nov''Dec');

Begin
  Result := Format('%s.%s.%s',[Copy (aDate,1,2),
    szMonths[strtoint(Copy (aDate,4,2))],
    Copy (aDate,7,2)])
End;

die funktion benötigt für 10,000,000 durchläufe auf meinem 3 ghz rechner 14 sekunden.
das sollte also durchaus ausreichen

aber so dauerts nur 1 sekunde:
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:
28:
Function QuickConvertDate (Const aDate : String) : String;
// (C) retnyg
Const
  szMonths : array [1..12of string[3] = ('Jan''Feb''Mar''Apr''May''Jun''Jul''Aug' , 'Sep''Oct''Nov''Dec');
var m,i: integer;
    p:pchar;
Begin
  i:=1;
  if adAte[4] = '0' then m := ord(adate[5])-48
  else m := ord(adate[5])-38;
  setlength(result,9);
  p:=@result[1];
  repeat
    case i of
    1: p^:= aDate[1];
    2: p^:= aDate[2];
    3: p^:= '.';
    4: p^:= szMonths[m][1];
    5: p^:= szMonths[m][2];
    6: p^:= szMonths[m][3];
    7: p^:= '.';
    8: p^:= aDate[7];
    9: p^:= aDate[8];
    end;
    inc(p);
    inc(i);
  until i = 10;
End;



viel mehr lässt sich auch mit asm nicht rausholen

Moderiert von user profile iconraziel: Beiträge zusammengefasst.

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: So 14.08.05 10:35 
Hi retnyg,
Die Aufgabe war: 03-Aug-05 --> 03.08.05. Was Du hier programmiert hast, ist aber : 03.08.05 --> 03-Aug-05. Das das schneller ist, und man für die Überführung von '08'->'Aug' ein Array nimmt, liegt auf der Hand.

Nachtrag:
1. Ich habe 'Aug'->8 mal als Version mit einer TStringlist (Sorted = True, IndexOf) probiert, aber das Ergebnis dauert doppelt so lang wie die POS-Variante. Wie programmiert man die Funktion 'Monatsnummer aus Name' mit einem Array möglichst schnell?

2. Hier also meine Version, die einen DEA benutzt, um den Monatsnamen in die Monatsnummer zu überführen. Man beachte die Komplexität im Vergleich zur 'grottenschlechten' aber eben minimalisitisch kompakten Version (Performancevergleich ca 10:1) sowie das völlige Fehlen einer Liste von Monatsnamen. Wir gehen stillschweigend davon aus, das nur gültige Monatsnamen im Datum vorkommen, eine Einschränkung, die auch für die Vergleichsalgorithmen gilt.

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:
// DateConvert
//
Var
  DateClass : Array [Char] Of ShortInt;

// Das hier soll eine Const-Deklaration sein, aber um zu verdeutlichen, wie
// die Daten zustande kommen, wurde eine Routine implementiert, die das Array
// füllt. Der Grundgedanke ist der, das 4 von 12 Monatsnamen im Englischen
// anhand des 1.Buchstabes klassifiziert werden können, der Rest kann durch
// Vergleiche des 2. bzw. 3. Buchstabens zugeordnet werden.
// DateClass nimmt nun die Klassifikation anhand des 1.Buchstabens vor.
// Ein positiver Wert bezeichnet den eindeutigen Monat, ein negativer Wert
// eine Fallunterscheidung. Man beachte, das die Gross/kleinschreibung des
// 1.Buchstabens ignoriert wird.

Procedure SetupDateClassConst;
Var
  i : Char;
Begin
  For i:= #0 to #255 do DateClass[i]:=0;
  DateClass ['j'] := -1; DateClass ['J'] := -1;
  DateClass ['f'] :=  2; DateClass ['F'] :=  2;
  DateClass ['m'] := -2; DateClass ['M'] := -2;
  DateClass ['a'] := -3; DateClass ['A'] := -3;
  DateClass ['s'] := 10; DateClass ['S'] := 10;
  DateClass ['n'] := 11; DateClass ['N'] := 11;
  DateClass ['D'] := 12; DateClass ['D'] := 12;
End;

Function ConvertDateFastest (Const aDate : String) : String;
Var
  m : Integer;
  
Begin
// ---- Monats-Hash à la Alzaimar mit DEA 2/3 Buchstabe ist case sensitiv ----
  m := DateClass[aDate[4]];
// Wenn < 0, dann Fallunterscheidung vornehmen
  case m Of
    -1 : -- Fälle Jan, Jun und Jul
      If aDate[5]='a' Then m := 1 else if aDate[6]= 'n' Then m := 6 else m:=7;
    -2 : -- Fälle Mar und May
      If aDate[6]='y' Then m:=5 Else m:=3;
    -3 : -- Fälle Apr und Aug
      If aDate[6]='r' Then m:=4 Else m:=8;
    End;
// ---------------------------------------------------------------------------
  SetLength (Result, 8);
  Result[1] := aDate[1]; // 1. Stelle des Tages kopieren
  Result[2] := aDate[2]; // 2. Stelle 
  Result[3] := '.';
  if m<10 then begin     // Monate 1..9 --> 01..09
    Result[4] := '0';
    Result[5] := Chr (m + 48);
    End
  Else Begin             // Monate 10,11 und 12 1:1
    Result[4] := '1';
    Result[5] := Chr (m + 38);
    End;
  Result[6] := '.';
  Result[7] := aDate[8]; // 1.Stelle Jahr
  Result[8] := aDate[9]; // 2.Stelle Jahr
End;

Das lässt sich normalerweise mit Assembler um einige Prozente steigern, oder?
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: So 14.08.05 15:39 
user profile iconalzaimar hat folgendes geschrieben:
Hi retnyg,
Die Aufgabe war: 03-Aug-05 --> 03.08.05. Was Du hier programmiert hast, ist aber : 03.08.05 --> 03-Aug-05. Das das schneller ist, und man für die Überführung von '08'->'Aug' ein Array nimmt, liegt auf der Hand.

ich habe mich einfach an den codeschnipsel von dir gehlaten und den optimiert :mrgreen:

user profile iconalzaimar hat folgendes geschrieben:
Das lässt sich normalerweise mit Assembler um einige Prozente steigern, oder?

ich habe mal meine quickconvert prozedur oben in assembler umgeschrieben. resultat: 18 % langsamer, als der von delphi optimierte asm-code.
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:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
Function ConvertDate3 (Const aDate : String) : String;
Const
  szMonths : array [1..12of string[3] = ('Jan''Feb''Mar''Apr''May''Jun''Jul''Aug' , 'Sep''Oct''Nov''Dec');
// das resultat der funktion ist nicht ganz richtig, es ging mir hier eher um den speed-test
begin
  asm
    pushad
  end;
  setlength(result,9);
  asm
    popad
    push ebx
    sub eax, 4
    test eax, eax
    jz @fin
    add eax, 8
    xor ecx, ecx
    cmp byte ptr[eax], 48
    jne @bigger10
    inc eax
    mov byte ptr[eax], cl
    sub cl , 48
//    push ecx
    jmp @haveMonth
    @bigger10:
    inc eax
    mov cl, byte ptr[eax]
    sub cl , 38
    //push ecx
    @haveMonth:
    sub eax, 5 // eax: adate, stack: m, ecx: i
    xor ecx, ecx
    mov edi, [result]
    mov edi, dword ptr [edi]

    @loopstart:
    mov edx, ecx
    lea  edx, edx*8
    lea edx, edx + @caseseg
    jmp +edx

    @caseseg:
    mov bl, byte ptr[eax]
    mov byte ptr[edi],   bl
    jmp @nextround
    nop
    nop

    @next:

    mov bl, byte ptr[eax]
    mov byte ptr[edi],   bl
    jmp @nextround
    nop
    nop

    @next2:
    mov byte ptr[edi], 46
    jmp @nextround
    nop
    nop
    nop

    @next3: // unfinished
    mov bl, byte ptr[eax]
    mov byte ptr[edi],   bl
    jmp @nextround
    nop
    nop

    @next4:
    mov bl, byte ptr[eax]
    mov byte ptr[edi],   bl
    jmp @nextround
    nop
    nop

    @next5:
    mov bl, byte ptr[eax]
    mov byte ptr[edi],   bl
    jmp @nextround
    nop
    nop

    @next6:
    mov byte ptr[edi], 46
    jmp @nextround
    nop
    nop
    nop

    @next7:
    dec eax
    mov bl, byte ptr[eax]
    mov byte ptr[edi],   bl
    jmp @nextround
    nop

    @next8:
    mov bl, byte ptr[eax]
    mov byte ptr[edi],   bl
    nop
    nop
    nop
    nop

    @nextround:
    inc eax
    inc edi
    inc ecx
    cmp ecx, 9
    jne @loopstart
    @ende:
  //  pop ecx
    xchg eax, edi
    @fin:
    pop ebx

  End;
end;

der delphi-compiler erzeugt ziemlich schnellen asm code, im normalfall besser als der coder.
für optimierungen bleibt genug platz im pascal-code ;)
edit: siehe hierzu ftp.untergrund.net/b...Assembler_-_xvid.avi

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...


Zuletzt bearbeitet von retnyg am So 14.08.05 15:51, insgesamt 1-mal bearbeitet
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: So 14.08.05 15:46 
user profile iconretnyg hat folgendes geschrieben:
user profile iconalzaimar hat folgendes geschrieben:
Hi retnyg,
Die Aufgabe war: 03-Aug-05 --> 03.08.05. Was Du hier programmiert hast, ist aber : 03.08.05 --> 03-Aug-05. Das das schneller ist, und man für die Überführung von '08'->'Aug' ein Array nimmt, liegt auf der Hand.

ich habe mich einfach an den codeschnipsel von dir gehlaten und den optimiert :mrgreen:

Nee, hast Du nich, Du hast die Umkehrfunktion erzeugt (auch nicht schlecht), aber das ist nebensächlich. Was mich absolut umhaut ist die Tatsache, das dein ASM lahmer ist, als Delphi. Ich krieg bei ASM immer Pickel also hier meine Frage... obwohl ich die lieber in einem anderen Thread posten würde:
Wird eine Case Anweisung als Jumptable oder als Folge von Abfragen realisiert?
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: So 14.08.05 15:57 
user profile iconalzaimar hat folgendes geschrieben:
Was mich absolut umhaut ist die Tatsache, das dein ASM lahmer ist, als Delphi. Ich krieg bei ASM immer Pickel also hier meine Frage... obwohl ich die lieber in einem anderen Thread posten würde:
Wird eine Case Anweisung als Jumptable oder als Folge von Abfragen realisiert?

kannst du selber gucken: breakpoint auf das case-statement und dann STRG-ALT-C
der code den delphi generiert ist so kryptisch, dass es äusserst schwer ist ihn zu analysieren
er ist aber sehr effizient

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: So 14.08.05 16:10 
Da muss ich widersprechen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
Case m of
  -1 : ...
  -2 : ...
  -3 : ...
end;

Erzeugt diesen Code (sinngemäss):
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
m := m -3;
if m=0 goto x;
dec (m);

if m=0 goto y;
dec (m);

if m=0 goto z;
dec (m);
// else part
...

Andere Case-Konstrukte erzeugen ähnlichen Code. Mein alter UCSD-Compiler (68k System) erzeugt aber eine Jumptable...

Fazit: Um der (für das Fortbestehen der Welt, des Universums und dem ganzen Rest unverzichtbaren :dunce: ) ConvertDate Funktion zu noch mehr Performance zu verhelfen, kann man CASE-Anweisungen mit Hilfe von (vorher definierten) Jumptabellen noch optimieren. Ich postuliere mal, das eine Anweisung:
ausblenden Delphi-Quelltext
1:
Goto JumpTable [m];					

das iterative Delphi-Compilat doch noch um Längen schlägt...
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: So 14.08.05 16:22 
user profile iconalzaimar hat folgendes geschrieben:
Ich postuliere mal, das eine Anweisung:
ausblenden Delphi-Quelltext
1:
Goto JumpTable [m];					

das iterative Delphi-Compilat doch noch um Längen schlägt...

das wage ich zu bezweifeln, denn im endeffekt kennt der assembler eh nur jumps

ich wollte grade mal deine funktion testen, aber der compiler meckert rum...
kannst du mal eine lauffähige variante posten ?

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: So 14.08.05 16:24 
Läuft hier:
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:
// Das hier soll eine Const-Deklaration sein, aber um zu verdeutlichen, wie
// die Daten zustande kommen, wurde eine Routine implementiert, die das Array
// füllt. Der Grundgedanke ist der, das 4 von 12 Monatsnamen im Englischen
// anhand des 1.Buchstabes klassifiziert werden können, der Rest kann durch
// Vergleiche des 2. bzw. 3. Buchstabens zugeordnet werden.
// DateClass nimmt nun die Klassifikation anhand des 1.Buchstabens vor.
// Ein positiver Wert bezeichnet den eindeutigen Monat, ein negativer Wert
// eine Fallunterscheidung
Var
  DateClass : Array [Char] Of ShortInt;

Procedure SetupDateClassConst;
Var
  i : Char;
Begin
  For i:= #0 to #255 do DateClass[i]:=0;
  DateClass ['j'] := -1; DateClass ['J'] := -1;
  DateClass ['f'] :=  2; DateClass ['F'] :=  2;
  DateClass ['m'] := -2; DateClass ['M'] := -2;
  DateClass ['a'] := -3; DateClass ['A'] := -3;
  DateClass ['s'] := 10; DateClass ['S'] := 10;
  DateClass ['n'] := 11; DateClass ['N'] := 11;
  DateClass ['D'] := 12; DateClass ['D'] := 12;
End;

Function ConvertDateFastest (Const aDate : String) : String;
Var
  m : Integer;

Begin
// ---- Monats-Hash à la Alzaimar --------------------------------------------
  m := DateClass[aDate[4]];
// Wenn < 0, dann Fallunterscheidung vornehmen
  case m Of
    -1 : If aDate[5]='a' Then m := 1 else if aDate[6]= 'n' Then m := 6 else m:=7;
    -2 : If aDate[6]='y' Then m:=5 Else m:=3;
    -3 : If aDate[6]='r' Then m:=4 Else m:=8;
    End;
//----------------------------------------------------------------------------
  SetLength (Result, 8);
  Result[1] := aDate[1];
  Result[2] := aDate[2];
  Result[3] := '.';
  if m<10 then begin
    Result[4] := '0';
    Result[5] := Chr (m + 48);
    End
  Else Begin
    Result[4] := '1';
    Result[5] := Chr (m + 38);
    End;
  Result[6] := '.';
  Result[7] := aDate[8];
  Result[8] := aDate[9];
End;


Einmal 'SetupDateClassConst' aufrufen und dann loslegen. Aber, nochmal. Die Funktion liefert:

ConvertDateFastest ('01-Aug-05')-->'01.08.05'