| |
VB.NET - Ein- und UmsteigerGeschwindigkeitsverlust die Zweite | | | Autor: mathemike | Datum: 03.07.12 09:33 |
| Hallo ! Ich habe wieder ein Problem mit einem Geschwindigkeitsverlust beim Umstieg von VB6 in VB.NET. Ich habe eine sehr große Textdatei (2GB), die Zeilen identischer Länge=100 enthält und die sortiert ist. Die Datei soll keinesfalls in eine Datenbank umgewandelt werden und kann auch nicht komplett im Speicher gehalten werden.
Der VB6-Zugriff in der Art
Dim wert as String*102
Open datei for Binary as #1
j=(i-1)*102+1
Get #1,i,wert 'Index ab 1
läuft für vorgegebenen Datensatz Nummer i nicht nur problemlos, sondern extrem schnell. Ich habe eine Suche per Intervallschachtelung drumrum geschrieben, die es mir erlaubt, einen Datensatz in weniger als einer Sekunde zu suchen. Die Länge=102 oben ergibt sich natürlich wegen der beiden Satzendezeichen.
Nun bin ich auf NET umgestiegen und habe die Zeilen wie folgt umgeschrieben :
Dim fs as Filestream, r as Binaryreader, wertc(101) as Char
fs = New Filestream(datei, Filemode.Openorcreate, Fileaccess.Readwrite)
r = New Binaryreader(fs)
j=(i-1)*102
r.Basestream.Position=j
wertc=r.Readchars(102)
wert=New String(wertc) 'Index ab 0
Das Ergebnis ist hier genauso wie beim VB6-Programm. Läuft gut und sicher für vorgegebene Datensatznummer i, erzeugt dieselben Ergebnisse (bis auf die kleine Indexverschiebung). Aber leider dauert der Zugriff circa doppelt so lange. Kann man das schneller hinbekommen ? Mit einem r.readstring klappt es irgendwie nicht. Die Zuweisung in ein Array wertc und dann in einem String wert ist irgendwie überflüssig oder nicht ? Wichtig dabei : Der binäre Zugriff muss unbedingt(!) sein. | |
Re: Geschwindigkeitsverlust die Zweite | | | Autor: Manfred X | Datum: 03.07.12 11:00 |
| Hallo!
Zunächst würde ich den Filestream anders parametrisieren.
Und dann direkt im FileStream lesen ...
fs = New IO.FileStream(Datei, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.None)
fs.Position / fs.read
Einfach mal probieren!
MfG
Manfred
Beitrag wurde zuletzt am 03.07.12 um 11:01:15 editiert. | |
Re: Geschwindigkeitsverlust die Zweite | | | Autor: mathemike | Datum: 03.07.12 12:59 |
| Danke für den Tipp. Ich habe das gerade mal ausprobiert in der Art
Dim enc as System.Text.Encoding = System.Text.Encoding.Default
Dim dummy(101) as Byte
fs.Position=j
fs.Read(dummy,0,102)
wert=enc.GetString(dummy)
Leider gab da keinen Geschwindigkeitsgewinn. Aber schön, dass der BinaryReader erstmal wegfällt. Problem ist nur : Wie lese ich ab der j.Stelle einen String der Länge=102 ein. Der fs.Read liest wohl nur Bytes ein, einen ReadString gibt es nicht. Um diese Bytes in einen Strirg zu bekommen, fällt mir nur obiges Encoding ein. Und das kostet wohl Zeit. Oder warum wird das ganze nicht schneller ? | |
Re: Geschwindigkeitsverlust die Zweite | | | Autor: Manfred X | Datum: 03.07.12 13:09 |
| Hallo!
So. Nun mal ein wenig ausführlicher.
Beim Zugriff auf einen Filestream erhälst Du die Bytefolge in der
Datei. Um daraus einen Text zu entschlüsseln, wird in Net ein
weiterer expliziter Schritt durchgeführt. Das erledigt z.B.
der Binaryreader, das tut er aber bei JEDEM Lesevorgang.
Genau genommen machst Du folgendes:
Using fs As New IO.FileStream(datei, IO.FileMode.Open, _
IO.FileAccess.Read, IO.FileShare.None), _
br As New IO.BinaryReader(fs, System.Text.UTF8Encoding.UTF8)
fs.Position = ...
'direkte Zuweisung der Zeichen auf Stringvariable
Dim text As String = br.ReadChars(100)
'......
End Using Eventuell benötigst Du nicht in allen Fällen die Text-Umwandlung (z.B. bei binärer
Suche in den sortierten Dateizeilen). In solchen Fällen könnte man einen direkten
Bytevergleich mit dem Suchmuster durchführen.
fs.position = ....
Dim bytes(99) as byte
fs.Read(bytes, 0, 100) 'Bytearray lesen
'Nur bei Bedarf in Bytes in Text wandeln
Dim Text As String = ByteArrayToTextString(bytes) Die Umwandlungsfunktion:
Public Function ByteArrayToTextString(ByVal bytes() As Byte) As String
Dim enc As System.Text.Encoding = System.Text.UTF8Encoding.UTF8
Return enc.GetString(bytes)
End Function Edit:
Hast Du diese "Textdatei" eigentlich defragmentiert?
MfG
Manfred
Beitrag wurde zuletzt am 03.07.12 um 13:22:01 editiert. | |
Re: Geschwindigkeitsverlust die Zweite | | | Autor: mathemike | Datum: 03.07.12 13:43 |
| Hallo nochmal. Ich habe das Encoden (wie von Dir beschrieben) im Binaryreader nun durchgeführt. Prinzipiell hatte ich das ja schon vorher in zwei Schritten drin. Eine Geschwindigkeitsänderung habe ich nicht bemerkt; vielleicht ein bißchen schneller. Der Code scheint jetzt wirklich ok und optimiert. Die gleiche Textdatei wird trotzdem von VB6 deutlich schneller bearbeitet als von VB.NET. Leider benötige ich über die ganze Stringlänge die Textumwandlung. Eine weitere Optimierung sehe ich nun nicht mehr. Mir ging es vor allem um den Unterschied zwischen VB6 und VB.NET. Dass man das Problem prinzipiell verbessert angehen kann, entnehme ich Deiner Bemerkung zur Textdefragmentierung. Habe ich bisher nicht durchgeführt. Werde ich noch tun - wenn ich rauskriege, was das ist . Solche Verbesserungen stehen dann vermutlich auch VB6 zur Verfügung. Ich melde mich, wenn ich weiter bin und möchte das Thema erstmal schließen. Vielen Dank !!! | |
Re: Geschwindigkeitsverlust die Zweite | | | Autor: FZelle (Moderator) | Datum: 03.07.12 14:02 |
| Auf dieses Problem wirst du in der .NET Welt ziemlich häufig treffen und der Grund ist sehr einfach.
VB6 arbeitet mit chars als String, .NET arbeitet intern immer mit Unicode.
Aber wie hier schon öfter erwähnt, manchmal lohnt es sich darüber nachzudenken den Hammer gegen etwas anderes auszutauschen. | |
Re: Geschwindigkeitsverlust die Zweite | | | Autor: mathemike | Datum: 03.07.12 14:14 |
| Was das Defragmentieren von Festplatten anbetrifft, bin ich im Bilde. Die Textdatei selber ist nicht fragmentiert. Daran liegt es nicht - sollte sich in VB6 als auch im VB.NET entsprechend auswirken. Wenn jemand wie Ihr sagt, es sei kein Wunder, dass VB.NET in diesem Fall(!) etwas langsamer ist als VB6, kann ich damit leben. Mir war das prinzipiell nicht klar. Solche Fragen muss ich dann wohl nicht mehr stellen. Ist auch eine Erkenntnis. Irgendwie hatte ich (um bei dem Bild zu bleiben) gedacht, VB6 ist der kleine Hammer, aber VB.NET der größere. Naja, mittlerweile merke ich zumindest, was VB.NET alles mehr kann. Nochmals Danke und Tschüß !!! | |
Re: Geschwindigkeitsverlust die Zweite | | | Autor: sv00010 | Datum: 03.07.12 18:43 |
| Eventuell kannst du die Teile, welche in vb6 schneller sind, in eine vb6-Dll auslagern und dann in VB.net als dll wieder einbinden. 0 | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
Neu! sevCoolbar 3.0
Professionelle Toolbars im modernen Design!
Mit sevCoolbar erstellen Sie in wenigen Minuten ansprechende und moderne Toolbars und passen diese optimal an das Layout Ihrer Anwendung an (inkl. große Symbolbibliothek) - für VB und MS-Access Weitere InfosTipp des Monats TOP Entwickler-Paket
TOP-Preis!!
Mit der Developer CD erhalten Sie insgesamt 24 Entwickler- komponenten und Windows-DLLs. Die Einzelkomponenten haben einen Gesamtwert von 1605.50 EUR...
Jetzt nur 599,00 EURWeitere Infos
|