Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Bessere Performance bei Stream?
lechner
myCSharp.de - Member



Dabei seit:
Beiträge: 20

Themenstarter:

Bessere Performance bei Stream?

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
Hajoseb
myCSharp.de - Member

Avatar #avatar-2670.jpg


Dabei seit:
Beiträge: 315

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
powerbond007
myCSharp.de - Member



Dabei seit:
Beiträge: 80

beantworten | zitieren | melden

Hi lechner,

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

Grüße
powerbond007
private Nachricht | Beiträge des Benutzers
lechner
myCSharp.de - Member



Dabei seit:
Beiträge: 20

Themenstarter:

beantworten | zitieren | melden

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

@powerbond007: Auch eine gute Idee

Werde beide gleich testen

Danke
private Nachricht | Beiträge des Benutzers
Hajoseb
myCSharp.de - Member

Avatar #avatar-2670.jpg


Dabei seit:
Beiträge: 315

beantworten | zitieren | melden

Kombiniere halt beides :evil:
"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.”
Anatole France
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo lechner,

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

herbivore
private Nachricht | Beiträge des Benutzers
lechner
myCSharp.de - Member



Dabei seit:
Beiträge: 20

Themenstarter:

Aw

beantworten | zitieren | melden

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
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von lechner am .
private Nachricht | Beiträge des Benutzers
Hajoseb
myCSharp.de - Member

Avatar #avatar-2670.jpg


Dabei seit:
Beiträge: 315

beantworten | zitieren | melden

Ä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
private Nachricht | Beiträge des Benutzers
unclesam
myCSharp.de - Member



Dabei seit:
Beiträge: 238
Herkunft: Nassau

beantworten | zitieren | melden

//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.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von unclesam am .
heute code ich, morgen debug ich und übermorgen cast ich die königin auf int
private Nachricht | Beiträge des Benutzers
Hajoseb
myCSharp.de - Member

Avatar #avatar-2670.jpg


Dabei seit:
Beiträge: 315

beantworten | zitieren | melden

@ 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 ???
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Hajoseb am .
"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.”
Anatole France
private Nachricht | Beiträge des Benutzers
Borg
myCSharp.de - Member



Dabei seit:
Beiträge: 1548
Herkunft: Berlin, Germany

beantworten | zitieren | melden

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;
}
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Borg am .
private Nachricht | Beiträge des Benutzers
Hajoseb
myCSharp.de - Member

Avatar #avatar-2670.jpg


Dabei seit:
Beiträge: 315

beantworten | zitieren | melden

Ob es noch kürzer geht ... 8)
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Hajoseb am .
"Zufall ist das Pseudonym Gottes, wenn er nicht selbst unterschreiben will.”
Anatole France
private Nachricht | Beiträge des Benutzers