Einzelnen Beitrag anzeigen

Sequitar

Registriert seit: 8. Jan 2016
74 Beiträge
 
Delphi 10.4 Sydney
 
#1

Effizienter binär-output eines (word)-streams

  Alt 5. Apr 2022, 19:22
Ich habe bei einem Algorithmus als output eine liste / einen stream, der werte des typs word (0..65535) enthält.
Jetzt würde ich die liste gerne wieder zu binaer wandeln (chars, bytes) und ausgeben (entweder in einen stream schreiben oder in einem string speichern):
Wie kann ich den output möglichst effizient (d.h. kurz) halten?

Bisher hatte ich folgende Ansätze:

naiv:
Delphi-Quellcode:
Function Tio_stream.OutputCompressedData(data: Tlist<Pword>)
  : Tmemorystream;
Var
  P: Pword;
  Writer: Tbinarywriter;
Begin
  Result := Tmemorystream.Create;
  Writer := Tbinarywriter.Create(Result);
  Try
    For P In Compressed Do
      Writer.Write(P^);
  Finally
    Writer.Free;
  End;
End;

//read

Procedure Tio_stream.GetCompressedData(Const Content: Tmemorystream;
  Out res: Tlist<Pword>);
Var
  Tempdata: Word;
Var
  Tempdataentry: Pword;
Var
  Readindex, Maxread: Word;
  Datasize: Integer;
Begin
//assert(assigned(res));
  Cleardata(res);
  Content.Position := 0;
  Begin
    Readindex := 0;
    Datasize := Sizeof(Word);
    Maxread := Content.Size Div Datasize;
    While Readindex < Maxread Do
    Begin
      Content.Read(Tempdata, Datasize);
      New(Tempdataentry);
      Tempdataentry^ := Tempdata;
      res.Add(Tempdataentry);
      Inc(Readindex);
    End;
  End;
End;
einmal noch als words/chars direkt (bisher das kürzeste):
Delphi-Quellcode:
procedure OutputCompressedData(Compressed: Tlist<Pword>): String;
Var
  Entry: Pword;
  Outchar: Pchar;
Begin
  Setlength(Result, Compressed.Count);
  Outchar := @Result[1];
  For Entry In Compressed Do
  Begin
    Outchar^ := Char(Entry^);
    Inc(Outchar);
  End;
  // Result := Concat(Result, Char(entry^));
End;
Darauf aufbauend hatte ich folgendes versucht (die super klassen tstreamwriter/reader habe ich erst vor kurzem für mich entdeckt)
Delphi-Quellcode:
Function Tlzwio_stringstream.OutputCompressedData
  (Compressed: Tlist<Pword>): String;
Var
  Temp: Tmemorystream;
  Encoding: Tencoding;
Begin
  Try
    Assert(Assigned(Compressed));
    Encoding := Tencoding.Create;
    Encoding.Default;
    // writes values as word to stream
    Temp := Inherited Outputcompresseddata(Compressed);
    Temp.Position := 0;
    With Tstreamreader.Create(Temp, Encoding) Do
    Begin
      Result := ReadLine; // abstract error
      Free;
    End;
  Finally
    Encoding.Free;
    Temp.Free;
  End;
End;
habe aber, wo angegeben, mit dem abstract error (welche klasse überschreibt das denn?) zu tun


Was haltet ihr davon? #Holzweg? Welche - im obigen sinne - effizienten Alternativen (bitstream klasse, sowas könnte ich an anderer stelle auch gebrauchen?)würdet ihr vorschlagen?

danke!
  Mit Zitat antworten Zitat