Laden...

Bessere Performance bei Stream?

Erstellt von lechner vor 16 Jahren Letzter Beitrag vor 16 Jahren 2.219 Views
L
lechner Themenstarter:in
19 Beiträge seit 2007
vor 16 Jahren
Bessere Performance bei Stream?

Guten Abend,

Ich habe folgendes Problem:
Ein MemoryStream (ms) enthält irgendwelche ASCII Zeichen.
Ich möchte dann nach jedem Byte ein beliebiges Zeichen einfügen, sagen wir mal z.B. 0.

Ich habe es wie folgt gelöst, da es aber mit einem String arbeitet ist es bei größeren Streams unglaublich langsam. Ein String kann halt nicht mit einem Stream mithalten.

Hier erstmal mein unglaublich langsames Programm:


//MemoryStream ms mit irgendeinem Inhalt

long cts2 = 0;
                byte[] STB2 = new byte[ms.Length];
                ms.Position = 0;
                while (cts2 < ms.Length)
                {
                    STB2[cts2++] = Convert.ToByte(ms.ReadByte());
                }
                
                
                ms.Position = 0;
                string str = null;
                foreach (byte p in STB2)
                {
                    str += p + "0";
                }
                System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
                
                ms = new MemoryStream(encoding.GetBytes(str));

Es muss doch eine andere Möglichkeit mit einer höheren Performance geben, also direkt über den Stream ohne den Umweg über den String zu nehmen??

Gruß,
lechner

309 Beiträge seit 2007
vor 16 Jahren

Idee: Einen 2., doppelt so großen MemoryStream erstellen ...
... aus Stream1 ein Zeichen lesen und in Stream2 das Zeichen + dem Zeichen '0' schreiben

mfg Hajoseb

**"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.” **
Anatole France

P
80 Beiträge seit 2007
vor 16 Jahren

Hi lechner,

ersetz den string durch einen StringBuilder. Für mehr Infos siehe :rtfm:

Grüße
powerbond007

L
lechner Themenstarter:in
19 Beiträge seit 2007
vor 16 Jahren

@Hajoseb: eine schnelle und gute Lösung, werde es gleich in die Tat umsetzen

@powerbond007: Auch eine gute Idee

Werde beide gleich testen

Danke

309 Beiträge seit 2007
vor 16 Jahren

Kombiniere halt beides 👍:evil:

**"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.” **
Anatole France

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo lechner,

was du machen willst klingt sehr nach dem, was Encoding.GetBytes macht.

herbivore

L
lechner Themenstarter:in
19 Beiträge seit 2007
vor 16 Jahren
Aw

Hallo,

@herbivore: encoding.GetBytes() verwende ich bereits, wie du bei meinem obigen Quellcode sehen kannst (letzte Zeile)

@powerbond007: Der StringBuilder ist leider auch nicht viel schneller als der String selber 😦.

Die Idee von Hajoseb ist nicht schlecht, doch ich habe ein Problem bei der Umsetzung: in einen Stream schreibe ich ja ein ByteArray,
ich möchte aber nach jedem Byte im ByteArray z.B. eine 1 haben.

Jetzt könnte ich mit einer foreach() Schleife das ByteArray lesen, das Byte in einen String und die 1, dann mit encoding.GetBytes() arbeiten und dann in den Stream schreiben.

Ganz schön umständlich, gibt es denn keinen einfacheren, besseren, schnelleren Weg???


//MemoryStream ms mit irgendeinem Inhalt:

ms.Position = 0;
byte[] buffer = new byte[ms.Length];
ms.Read(buffer, 0, buffer.Length);

foreach (byte p in buffer)
{
    string s = "";
    s = p.ToString() + "1";
    ms.Write(Encoding.ASCII.GetBytes(s), ms.Position, s.Length);
}

Jemand eine bessere Idee??

Danke

309 Beiträge seit 2007
vor 16 Jahren

Äh ...

(Sorry, wenn ich jetzt nciht "richtiges C# schreibe, aber da müste ich erst zu lange überlegen. Habe C# noch nicht im Blut. Also eher eine Art Alorythmen-Schreibweise)

Schleife X von 0 bis Anzahl der Bytes
Lesen Element aus Stream1 bei X
Schreiben Element in Stream2 bei X << 1 (= X*2, roll geht schneller)
Schreiben "1" (oder was du brauchtst) in Stream2 bei (X << 1)+1

Mfg Hajoseb

**"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.” **
Anatole France

U
237 Beiträge seit 2007
vor 16 Jahren
//MemoryStream ms mit irgendeinem Inhalt:

ms.Position = 0;
byte[] buffer = new byte[ms.Length];
byte[] endArray = new byte[ms.Length*2]; //doppelte größe
ms.Read(buffer, 0, buffer.Length);
int x = 0;

foreach(byte p in buffer)
{
    endArray[x] = p;
    endArray[x+1] = (byte) 1;
    x += 2;
}

habs nicht getestet. damit kann man aber strings umgehen.

heute code ich, morgen debug ich und übermorgen cast ich die königin auf int

309 Beiträge seit 2007
vor 16 Jahren

@ unclesam: Danke 👍


//MemoryStream ms mit irgendeinem Inhalt:

ms.Position = 0;
byte[] buffer = new byte[ms.Length];
byte[] endArray = new byte[ms.Length*2]; //doppelte größe
ms.Read(buffer, 0, buffer.Length);
int x = -1;  // Damit das 1. schreiben bei 0 erfolgt ...

foreach(byte p in buffer)
{
    endArray[++x] = p;            // ++x dürfte schneller als x+1 sein ...
    endArray[++x] = (byte) 1;
} 

Noch etwas schneller, oder ???

**"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.” **
Anatole France

B
1.529 Beiträge seit 2006
vor 16 Jahren

Na wenn dann mit Post-Inkrement und ohne Kopieren des MemoryStreams.

byte[] endArray = new byte[ms.Length << 1]; //doppelte größe
int x = 0;
foreach(byte p in ms.GetBuffer())
{
    endArray[x++] = p;
    endArray[x++] = (byte) 1;
}
309 Beiträge seit 2007
vor 16 Jahren

Ob es noch kürzer geht ... 8)

**"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.” **
Anatole France