Ich bin nur 6 Jahre zu spät, aber vielleicht kann ich jemand anderem helfen.
Hier sind einige Richtlinien, die ich verwenden würde:
- Wenn die Möglichkeit besteht, dass die Daten in Zukunft nicht mehr passen, verwenden Sie den größeren int-Typ.
- Wenn die Variable als Struktur- / Klassenfeld verwendet wird, wird sie standardmäßig aufgefüllt, um ohnehin die gesamten 32-Bit zu belegen, sodass durch die Verwendung von Byte / Int16 kein Speicherplatz gespart wird.
- Wenn die Variable nur von kurzer Dauer ist (wie in einer Funktion), helfen die kleineren Datentypen nicht viel.
- "byte" oder "char" können die Daten manchmal besser beschreiben und die Kompilierungszeit überprüfen, um sicherzustellen, dass ihnen nicht versehentlich größere Werte zugewiesen werden. Wenn Sie beispielsweise den Tag des Monats (1-31) mit einem Byte speichern und versuchen, ihm 1000 zuzuweisen, wird ein Fehler verursacht.
- Wenn die Variable in einem Array von ungefähr 100 oder mehr verwendet wird, würde ich den kleineren Datentyp verwenden, solange dies sinnvoll ist.
- Byte- und Int16-Arrays sind nicht so threadsicher wie ein Int (ein Grundelement).
Ein Thema, das niemand angesprochen hat, ist der begrenzte CPU-Cache. Kleinere Programme werden schneller ausgeführt als größere, da die CPU mehr Programme in die schnelleren L1 / L2 / L3-Caches einpassen kann.
Die Verwendung des int-Typs kann zu weniger CPU-Anweisungen führen, erzwingt jedoch auch, dass ein höherer Prozentsatz des Datenspeichers nicht in den CPU-Cache passt. Anweisungen sind billig auszuführen. Moderne CPU-Kerne können 3-7 Befehle pro Taktzyklus ausführen, ein einzelner Cache-Fehler kann jedoch 1000-2000 Taktzyklen kosten, da er bis zum RAM reichen muss.
Wenn Speicherplatz gespart wird, führt dies auch dazu, dass der Rest der Anwendung eine bessere Leistung erbringt, da er nicht aus dem Cache herausgedrückt wird.
Ich habe einen schnellen Summentest mit Zugriff auf zufällige Daten in zufälliger Reihenfolge durchgeführt, wobei sowohl ein Byte-Array als auch ein Int-Array verwendet wurden.
const int SIZE = 10000000, LOOPS = 80000;
byte[] array = Enumerable.Repeat(0, SIZE).Select(i => (byte)r.Next(10)).ToArray();
int[] visitOrder = Enumerable.Repeat(0, LOOPS).Select(i => r.Next(SIZE)).ToArray();
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
int sum = 0;
foreach (int v in visitOrder)
sum += array[v];
sw.Stop();
Hier sind die Ergebnisse in der Zeit (Ticks): (x86, Release-Modus, ohne Debugger, .NET 4.5, I7-3930k) (kleiner ist besser)
________________ Array Size __________________
10 100 1K 10K 100K 1M 10M
byte: 549 559 552 552 568 632 3041
int : 549 566 552 562 590 1803 4206
- Der zufällige Zugriff auf 1 Million Elemente mit Byte auf meiner CPU führte zu einer Leistungssteigerung von 285%!
- Alles unter 10.000 war kaum wahrnehmbar.
- int war für diesen Basissummentest nie schneller als Byte.
- Diese Werte variieren je nach CPU mit unterschiedlichen Cache-Größen.
Ein letzter Hinweis: Manchmal schaue ich mir das jetzt Open-Source-.NET-Framework an, um zu sehen, was die Experten von Microsoft tun. Das .NET Framework verwendet überraschend wenig Byte / Int16. Ich konnte eigentlich keine finden.