Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi ASCII <-> ANSI (https://www.delphipraxis.net/257-ascii-ansi.html)

Daniel B 25. Jun 2002 15:02


ASCII <-> ANSI
 
Hi,

ich muss bestimmte teile einer recht "grossen" Datei(ca. 10-100Kb), beim Laden von Ascii in Ansi umwandeln und beim speichern dann wieder von ansi in ascii.

Nun meine Frage, macht es sinn nur diese Bestimmten stellen zu ändern? Oder soll ich einfach die ganze Datei umwandeln.

Bitte kein Source, da ich ncihts ausprobieren kann, nur theorie.

sakura 25. Jun 2002 15:19

Wenn die "bestimmten Stellen" nur einen geringen Teil ausmachen, dann macht es bestimmt Sinn, nur diese zu konvertieren. Wenn es sich dabei um einen Großteil der Datei handelt, dann solltest Du wohl einfach alles konvertieren.

P.S. auch 100KB sollten auf heutigen Rechnern in Bruchteilen einer Sekunde zu schaffen sein.
P.P.S. Wie willst Du die Konvertierung machen. Keine Theorie, bitte den Code, ich kann testen :D

Daniel B 25. Jun 2002 15:52

Diese bestimmten Stellen, machen nur 10% der Datei aus.
Es handelt sich dabei um Namen, die bis zu 10 Zeichen haben können.

X-Dragon 5. Dez 2003 10:06

Zitat:

Zitat von sakura
...
P.P.S. Wie willst Du die Konvertierung machen. Keine Theorie, bitte den Code, ich kann testen :D

Ok wenn du unbedingt was testen willst, ich hab hier was :):

Delphi-Quellcode:
function TFmHaupt.AnsiToIBMAscii(s: String): String;
{**************************************************}
var
  i : Integer;
begin
  for i := 1 to Length(s) do
    case s[i] of
      #196: Result := Result + #142; // von Ä
      #214: Result := Result + #153; // von Ö
      #220: Result := Result + #154; // von Ü
      #228: Result := Result + #132; // von ä
      #246: Result := Result + #148; // von ö
      #252: Result := Result + #129; // von ü
      #223: Result := Result + #225; // von ß
      else Result := Result + s[i];
    end;
end;
oder, was ich gerade gefunden habe:

Delphi-Quellcode:
function ANSI2ASCII(AText:string):string;
const MaxLength = 255;
var PText : PChar;
begin
  PText:=StrAlloc(MaxLength);
  StrPCopy(PText,AText);
  {$IFDEF WIN32}
  CharToOEM(PText,PText); {32Bit}
  {$ELSE}
  AnsiToOEM(PText,PText); {16Bit}
  {$ENDIF}
  Result:=StrPas(PText);
  StrDispose(PText);
end;
... allerdings ist der Code laut Delphi 6 "veraltet", also "StrDispose" sollte z.B. nicht mehr eingesetzt werden.

Mein Problem ist aktuell das ich eine seeehr große Datenmenge umwandeln muss, allerdings kein Text sondern sehr viele Datensätze (> 200.000 á 7 Felder á ca. 8 Zeichen macht als min. 11 Mio. Zeichen). Was ist denn jetzt wohl schneller (und auch sicher)? Oder weiß jemand eine bessere Möglichkeit?

choose 5. Dez 2003 10:23

Zitat:

Zitat von X-Dragon
Was ist denn jetzt wohl schneller (und auch sicher)? Oder weiß jemand eine bessere Möglichkeit?

Hallo X-Dragon,

Deine erste Variante ist langsamer, weil Du die Länge des Strings mit dem Anhängen jedes Zeichens veränderst, so dass nicht nur die Längenangabe aktualisiert sondern ggf auch nachträglich Speicher alloziiert werden muss...
Abhilfe könnte hier eine Lösung der Form
Delphi-Quellcode:
  Result:= AnInput;
  for iChar:= Length(Result) downto 1 do
    case Result[iChar] of
      foo: Result[iChar]:= bar;
    end;
schaffen.

Weil die Konvertierung ASCII<->ANSI keine Änderung in der Länge des Strings zur Folge hat, könntest Du bei den Aufrufen der API-Funktionen auch gecastete Strings übergeben, also zB (ungetestet, insbesondere bei 16Bit (Delphi 1?!) bin ich mit nicht sicher)
Delphi-Quellcode:
function ANSI2ASCII(const AnInput: string): string;
begin
  SetLength(Result, Length(AnInput);
  {$IFDEF WIN32}
  CharToOEM(PChar(AnInput), PChar(Result)); {32Bit}
  {$ELSE}
  AnsiToOEM(PChar(@AnInput[1]), PChar(@Result[1])); {16Bit}
  {$ENDIF}
end;
so dass Du das Problem mit StrAlloc, etc. geschickt umgehen kannst...

X-Dragon 5. Dez 2003 10:59

Re: ASCII <-> ANSI
 
Hab mal meine erste Methode mit deiner unteren vergleichen und jeweils die Zeit gestoppt.

Für Konvertierung der Datensätze 2.000-12.000 brauchte deine Methode 43 sek. und meine 39 sek ... :gruebel:.

Ich hatte eigentlich auch angenommen das deine schneller wäre ...

[edit]
die 2. Variante von mir liegt bei 35 sek. ...

choose 5. Dez 2003 11:41

Re: ASCII <-> ANSI
 
Hallo X-Dragon,

ich habe einen (relativ aufwendigen) Test durchgeführt. Die vorgeschlagene Lösung ist bei 131072 Strings der Länge 8 bis zu 784,125 mal schneller nach meinen Messungen.

Bitte öffne einen neuen Thread, falls Dich die Implementierung, die Ergebnisse der Zeitmessung (Phänomen: "Alte" Lösung wird zunehmend langsamer (18,759 mal nach 8 Iterationen)) oder ein Profilerlauf, den ich starten könnte, interessiert.

X-Dragon 5. Dez 2003 11:53

Re: ASCII <-> ANSI
 
Zitat:

Zitat von choose
Hallo X-Dragon,

ich habe einen (relativ aufwendigen) Test durchgeführt. Die vorgeschlagene Lösung ist bei 131072 Strings der Länge 8 bis zu 784,125 mal schneller nach meinen Messungen.

Bitte öffne einen neuen Thread, falls Dich die Implementierung, die Ergebnisse der Zeitmessung (Phänomen: "Alte" Lösung wird zunehmend langsamer (18,759 mal nach 8 Iterationen)) oder ein Profilerlauf, den ich starten könnte, interessiert.

Ja interessiert mich auf jeden Fall, aber wie soll ich den Thread denn nennen? Im Prinzip ist es hier doch genau richtig :gruebel:.

Und welche Lösung ist jetzt schneller als welche andere? :roteyes:

Achja die Länge der Strings ist übrigens max. 12 Byte, aber auch die Beschränkung der allozierten Speichermenge brachte zumindest bei 10.000 Datensätzen noch keinen messbaren Unterschied (vielleicht sollte ich mal den Speicherverbrauch des Programms überwachen beim umrechnen ...).

[edit]
Zumindestens bei den ersten 80.000 konnte bisher keine Verlangsamung der alten Methode festellen, sind immer ca 35 sek./10.000 Datensätze.

[edit2]
... hab mal ein wenig den Code für die Statusanzeige angepaßt, bin jetzt bei ca 5 sek./10.000 Datensätze, aber bin für alles offen was es noch schneller macht :angle2:


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:30 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz