AGB  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Base64/ Mime für Dateien

Ein Thema von Capstone · begonnen am 13. Sep 2017 · letzter Beitrag vom 17. Sep 2017
Antwort Antwort
Seite 2 von 2     12
Foren-Tage 2017
DIE Konferenz für Delphi-Entwickler mit vielen Vorträgen und ganztägigen Workshops, veranstaltet u.A. von der Delphi-PRAXiS und Embarcadero.
21.-23. September 2017 in Hamburg · Mehr Infos unter forentage.de.
Benutzerbild von Capstone
Capstone

Registriert seit: 15. Jul 2013
Ort: NRW
23 Beiträge
 
Delphi 3 Professional
 
#11

AW: Base64/ Mime für Dateien

  Alt 15. Sep 2017, 23:01
Habe das bei mir mit 90 MB getestet, dauerte etwa zwei Sekunden. Aber das war 'ne SSD. Mach mal die Ticks nur um meine Methode. Die sollte deutlich unter einer Sekunde brauchen, gerade für nur 17 MB.
nur um Deine Methode? Hab ich das nicht?
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:
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;
das ganze Projekt hab ich mal hier raufgeladen.

dazu auf Zippy eine ca. 1o MB Binary.
http://www92.zippyshare.com/v/JVjY2Swk/file.html
Angehängte Dateien
Dateityp: zip memstr.zip (163,4 KB, 3x aufgerufen)
MySQL-ERROR(): 1146
- - - Entschuldigung,
Diese Signatur ist in Deinem Land nicht vollständig sichtbar. :/
PGP Key ID: 0xB54AACD6
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
108 Beiträge
 
Delphi 2009 Professional
 
#12

AW: Base64/ Mime für Dateien

  Alt 16. Sep 2017, 08:51
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.
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
Benutzerbild von Capstone
Capstone

Registriert seit: 15. Jul 2013
Ort: NRW
23 Beiträge
 
Delphi 3 Professional
 
#13

AW: Base64/ Mime für Dateien

  Alt 16. Sep 2017, 09:54
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
MySQL-ERROR(): 1146
- - - Entschuldigung,
Diese Signatur ist in Deinem Land nicht vollständig sichtbar. :/
PGP Key ID: 0xB54AACD6

Geändert von Capstone (16. Sep 2017 um 10:00 Uhr)
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
108 Beiträge
 
Delphi 2009 Professional
 
#14

AW: Base64/ Mime für Dateien

  Alt 16. Sep 2017, 16:53
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:
Output.Size := ((Input.Size + 2) div 3) * 4; Wenn das noch immer nicht schneller geht, müsste man per Pointer in den Stream schreiben. Melde dich, ich ändere die Methode.
Angehängte Dateien
Dateityp: 7z SimpleBase64.7z (198,5 KB, 0x aufgerufen)
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
108 Beiträge
 
Delphi 2009 Professional
 
#15

AW: Base64/ Mime für Dateien

  Alt 17. Sep 2017, 17:26
Die Methode von mir hatte zwei Fehler, was zu einem ungültigen Ergebnis führte. Hier die korrekte Version:
Delphi-Quellcode:
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;
Hier übrigens der Dekoder:
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;
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:03 Uhr.
Powered by vBulletin® Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2017 by Daniel R. Wolf