![]() |
AW: Base64/ Mime für Dateien
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Der Sprung in die Function sollte doch nicht so lange brauchen, oder? höchtens 3 CPU Takte. oder wo genau meinst Du? und an einer HDD (vs. SSD) sollte das doch auch nicht liegen. Die hat immerhin schon 1 TB und ist erst 4 Jahre alt. Wieviel Umdrehungen hat die? 5000/s? ist ja komisch. Also ich verwende nur meinen Code hier (repost:)
Delphi-Quellcode:
das ganze Projekt hab ich mal hier raufgeladen.
procedure TForm1.Button1Click(Sender: TObject);
var Input, Output: TMemoryStream; STRI, FN: string; gt, gt2: Longword; diff: integer; begin Input := TMemoryStream.Create; Output := TMemoryStream.Create; try FN := '.\neu.txt'; gt := gettickcount; Input.LoadFromFile(FN); Base64EncodeStream(Input, Output); Output.SaveToFile(FN + 'b64'); gt2 := gettickcount; diff := gt2 - gt; // diff := diff * 1000; memo1.Text := inttostr(diff); finally Input.Free; Output.Free; end; end; dazu auf Zippy eine ca. 1o MB Binary. ![]() |
AW: Base64/ Mime für Dateien
Ich meinte mit "meiner Methode" nicht die TMemoryStream-Methoden zum Laden und Speichern. Mich würde interessieren, ob deine CPU so langsam ist, das damalige Delphi so ineffizient oder woran es sonst liegt.
|
AW: Base64/ Mime für Dateien
Guten Morgen,
ja, war ja auch nicht als Kritik gemeint. (das würd ich mir gegenüber einem Delphi-Erfahrenen, zudem Helfenden nicht wagen.) Hatte nach dem Posten noch die gettickcount noch ditrekt vor und hinter Deine Funktion gesetzt und compiliert. Brachte aber bei ner 10 MB Datei nur etwa 1 Sekunde Unterschied. (ca. 7000 statt ~6000 Tics) Hab dann auch ne 100 MB Datei versucht - und mußte das Programm nach 7 Minuten killen. Der kam gar nicht voran - unter Vollast!. ***** Das Programm wurde nach anfänglichem Fehlerüberprüfen in der IDE (klappte sogar mit 2 MB zügig in der IDE) später stets separat, außerhalb der IDE gestartet. (also der Debugger kann's nicht verzögern). ***** Meine Exe hab ich ja mit hochgeladen. Falls Du das in ner Sandbox laufen lassen möchtest. (Viren/Trojaner/Schadecode frei sollte es sein - ist nur mit STRG+F9 compiliert worden) Ja, die Gedanken kamen mir natürlich auch, ob meine Delphi D5 so ineffizient wäre. (aber ansich kann ich mir das nicht vorstellen, daß die damals dem Compiler so schlecht programmiert haben. OK, langsamer als ein M$ Compiler ... könnte er sein ... aaber eigentlich gibt es ja da nicht viel komplizierte Funktionen zu übersetzen. Das müßte ja schon resourcensparsam zur Exe zusammengekleistert sein, oder doch?)[die hatten doch schon 30 Jahre Erfahrung mit Compilerbau] Ich hab ja nichts verändert, wie man im Projekt ja sehen kann. Nur eingebaut und die Zeitmessung hinzugefügt. OK, mein Laptop ist nun 4 Jahre alt. Hat nur 8 GB RAM und nur 2x 2,54 GHz und 2 lausige Grafikkarten (Intel intern und 2GB nvidia auf dem Board obendrauf). Die 1 TB Festplatte drin. Mit 5400 U/m. Kein wassergekühlter highend Zocker-PC also. Abgesehn von Delphi und Windows spiele ich ja auch nicht :) Für Wörd und Exzel reicht der ja allemal. Aber was sollte da so langsam sein? OK, ich könnte ja auch die Datei vorher in den Speicher laden. Doch daß es daran liegt glaub ich nicht. Naja, vielleicht steckt in den 20 MB/ 2M Executables von heute doch effizientere Übersetzung. Eigenartig. Magst Du mal ggf. Deine Exe hochladen? LG |
AW: Base64/ Mime für Dateien
Liste der Anhänge anzeigen (Anzahl: 1)
Glückwunsch. Dein Delphi ist einfach nur scheißen-langsam.
Angehängt ist ein Kompilat deines Projekts mit Delphi 2009. Ich habe nichts gemacht außer es geöffnet und F9 gedrückt, dadurch wurde das Programme einige hundert Mal schneller. Das Kompilat meines Projekts ist auch angehängt, auch wenn es nichts bringt. Wenn du willst, ersetze mal beide WriteBuffer durch Write. Die beiden sind eigentlich identisch, aber wer weiß. Ein mögliches Problem wäre das zu feine Reservieren von Speicher. Füge doch einfach mal vor der for-Schleife folgende Zeile ein:
Delphi-Quellcode:
Wenn das noch immer nicht schneller geht, müsste man per Pointer in den Stream schreiben. Melde dich, ich ändere die Methode.
Output.Size := ((Input.Size + 2) div 3) * 4;
|
AW: Base64/ Mime für Dateien
Die Methode von mir hatte zwei Fehler, was zu einem ungültigen Ergebnis führte. Hier die korrekte Version:
Delphi-Quellcode:
Hier übrigens der Dekoder:
procedure Base64EncodeStream(Input, Output: TStream);
const Base64: array[0..64] of Byte = ( 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, 97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122, 48,49,50,51,52,53,54,55,56,57,43,47,$3D); var count: Byte; temp: Cardinal; i, j: Integer; begin Temp := 0; Count := 3; Output.Size := (Input.Size + 2) div 3 * 4; for i := 0 to (Input.Size + 2) div 3 - 1 do begin Count := Input.Read(temp, 3); temp := temp and $ff00 + temp shl 16 + temp shr 16 and $ff; // Endianness drehen (vereinfacht weil nur 3 Byte verwendet) for j := 0 to Count do begin Output.Write(Base64[temp shr 18 and $3f], 1); temp := temp shl 6; end; end; for j := Count to 2 do Output.Write(Base64[64], 1); // Schreibe ein Gleichzeichen zum Auffüllen end;
Delphi-Quellcode:
procedure Base64DecodeStream(Input, Output: TStream);
const Base64: array[Byte] of ShortInt = ( -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, -1, 0, 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,-1,-1,-1,-1,-1, -1,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,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1); var count, b: Byte; temp: Cardinal; i: Integer; begin Temp := 0; Count := 0; Output.Size := Trunc(Input.Size / 4 * 3); // maximal möglichen Output reservieren for i := 0 to Input.Size - 1 do begin Input.Read(b, 1); if Base64[b] > -1 then begin temp := temp shl 6 or Byte(Base64[b]); inc(Count); if Count = 4 then begin temp := temp and $ff00 + temp shl 16 + temp shr 16; // Endianness drehen (vereinfacht weil nur 3 Byte verwendet) Output.Write(temp, 3); temp := 0; Count := 0; end; end; end; if Count > 1 then // Rest behandeln, der kein 3er-Block ist (ein Base64-Rest kann nicht 1 lang sein) begin temp := temp shl (6 * (4 - Count)); temp := temp and $ff00 + temp shl 16 + temp shr 16; Output.Write(temp, Count - 1); end; Output.Size := Output.Position; // Scheint entgegen der Dokumentation TMemoryStream.Memory nicht zu löschen end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:53 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