Autor |
Beitrag |
AXMD
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: So 20.04.08 17:28
Hallo!
Ich arbeite momentan an einem Programm, das oft (mehrmals pro Sekunde) Zahlen formatieren muss, um genau zu sein soll eine Anzahl Bytes in einen String mit 3 Nachkommastellen konvertiert werden und die Präfixe K, M, G,... etc. angehängt werden. Folgenden Code habe ich bisher:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| public static string FormatBytes(long Bytes) { if (Bytes < 0) return "?"; char[] Prefixes = { 'K', 'M', 'G', 'T', 'P', 'E' }; int Prefix = -1; long TempBytes = Bytes; while ((TempBytes = (TempBytes >> 10)) != 0) Prefix++; if (Prefix == -1) return Bytes.ToString() + " Bytes"; else { long Total = Bytes >> ((Prefix + 1) * 10); long Fractal = (Bytes >> (Prefix * 10)) & 0x3FF; Fractal = (Fractal * 1000) >> 10; return Total.ToString() + System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator + Fractal.ToString("000") + " " + Prefixes[Prefix].ToString() + "B"; } } |
Er ist schon um einiges schneller als eine while-Schleife mit float-Operationen, aber da könnte man doch bestimmt noch mehr optimieren, oder  ? Vor allem die Zeile Fractal = (Fractal * 1000) >> 10; könnte man doch vielleicht ohne Multiplikation hinbekommen. Die Frage ist nur wie - die Genauigkeit sollte nicht spürbar leiden. Welche Optimierungspotenziale gibt es hier noch?
AXMD
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Mo 21.04.08 10:43
Hi!
Anfangen würde ich damit, das Array nicht jedes Mal von Neuem zu definieren, sondern als readonly-Feld der Klasse zu machen. Auch könntest Du schauen, ob String.Format schneller ist, als eine String-"Addition".
Bist Du sicher, dass die Methode der Flaschenhals ist? Und macht das eigentlich Sinn, mehrmals die Sekunde einen Wert zu aktualisieren?
Grüße
Christian
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mo 21.04.08 11:50
Ferner gilt auch für emulierte Sprachen auf virtuellen Maschinen: Vergleiche mit 0 sind schneller.
Was Du also machen solltest, ist ne Index-Verschiebung einzubauen, so dass Index 0 nen Leerstring enthält (B hat ja keinen Präfix).
Ferner solltest Du schauen, dass Du Ki statt K schreibst (ist "konformer").
Insgesamt würde dass dann so aussehen:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| readonly char[] Prefixes = { 'K', 'M', 'G', 'T', 'P', 'E' }; public static string FormatBytes(long Bytes) { if (Bytes < 0) return "?"; int Prefix = 0; long TempBytes = Bytes; while ((TempBytes = (TempBytes >> 10)) != 0) Prefix++; if (0 == Prefix) return Bytes.ToString() + " Bytes"; else { long Total = Bytes >> ((Prefix) * 10); long Fractal = (Bytes >> ((Prefix - 1) * 10)) & 0x3FF; Fractal = (Fractal * 1000) >> 10; return Total.ToString() + System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator + Fractal.ToString("000") + " " + Prefixes[Prefix].ToString() + "iB"; } } |
Ungetestet ...
HTH.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Mo 21.04.08 13:23
Christian S. hat folgendes geschrieben: | Bist Du sicher, dass die Methode der Flaschenhals ist? Und macht das eigentlich Sinn, mehrmals die Sekunde einen Wert zu aktualisieren?  |
Die Methode ist kein Flaschenhals in dem Sinn - sie benötigt nur im Vergleich zu den anderen Aktualisierungsoperationen die meiste Zeit, da sie öfters aufgerufen wird.
BenBE hat folgendes geschrieben: | Ferner gilt auch für emulierte Sprachen auf virtuellen Maschinen: Vergleiche mit 0 sind schneller.
Was Du also machen solltest, ist ne Index-Verschiebung einzubauen, so dass Index 0 nen Leerstring enthält (B hat ja keinen Präfix). |
Werd ich machen, das klingt sinnvoll. Allerdings hätt ich statt "B" gerne "Bytes" angezeigt - lässt sich das in diesem Konzept ohne viel Aufwand realisieren?
BenBE hat folgendes geschrieben: | C#-Quelltext |
Mit 64 Bit lassen sich trotzdem keine 70 Bit darstellen, und die FileStreams in .NET liefern alle maximal 64-Bit-Längen bzw. -Positionen
Danke erstmal für die Tipps, werde das integrieren und mir ansehen, wie sich die Laufzeit verändert.
AXMD
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mo 21.04.08 13:34
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
|