Frage

Ich habe eine fragwürdige Codierung der Praxis.

Wenn ich brauche durch eine kleine Liste von Elementen Grenze, deren Zählung unter 32000 ist iterieren, verwende ich Int16 für meinen i Variablentyp statt Integer. Ich tue dies, weil ich die Int16 nehmen Verwendung ist effizienter als eine vollständige geblasen Integer.

Bin ich falsch? Gibt es keinen effektiven Performance-Unterschied zwischen einem Int16 vs einem Integer mit? Soll ich mit Int16 stoppen und nur Stick mit Integer für alle meine Zähl- / Iteration Bedürfnisse?

War es hilfreich?

Lösung

Nach der unter Bezugnahme, die Laufzeit optimiert die Leistung von Int32 und empfiehlt sie für Zähler und andere häufig zugegriffen Operationen.

Aus dem Buch: MCTS Paced Training Kit (Prüfung 70-536): Microsoft .NET Framework 2.0-Application Development Foundation

Kapitel 1: "Rahmen Fundamentals"
Lektion 1: "Verwenden von Wertetypen"

  

Best Practices: Optimierung der Leistung   mit eingebauten Typen

     

Die Laufzeit optimiert die Leistung der 32-Bit-Integer-Typen (Int32 und UInt32), so dass diese Typen für Zähler und andere häufig zugegriffen Integralvariablen verwenden.

     

Für Gleitkommaoperationen, Double ist die effizienteste Art, da diese Operationen durch Hardware optimiert sind.

Auch Tabelle 1-1 in der gleichen Abschnitt listet für jeden Typen empfohlen verwendet. Relevant für diese Diskussion:

  • Int16 - Inter-Operabilität und andere spezialisierte Anwendungen
  • Int32 - Ganze Zahlen und Zähler
  • Int64 - große ganze Zahlen

Andere Tipps

Sie sollten fast immer Verwendung Int32 oder Int64 (und, nein, Sie nicht bekommen Kredit von UInt32 oder UInt64 verwenden), wenn sie über ein Array oder eine Sammlung von Index Looping.

Der offensichtlichste Grund, dass es weniger effizient ist, dass alles Arrays und Sammlung Indizes in der BCL gefunden Int32s nehmen, so dass eine implizite Umwandlung ist immer geht in Code geschehen, die Int16s als zu verwenden versuchen Index.

Der weniger offensichtliche Grund (und der Grund, dass Arrays Int32 als Index nehmen) ist, dass die CIL-Spezifikation besagt, dass alle Betriebs-Stack-Werte entweder Int32 oder Int64. Jedes Mal, wenn entweder Lade oder Speicher einen Wert zu irgendeiner anderen ganzen Zahl Typ (Byte, SByte, UInt16, Int16, UInt32 oder UInt64), gibt es eine implizite Umwandlungsoperation beteiligt. Unsigned Typen haben keine Strafe für das Laden, aber für den Wert zu speichern, bedeutet dies eine Verkürzung und eine mögliche Überlaufprüfung. Für die signierten Typen alle Last Sign-erstreckt, und alle Speicherzeichen-Einstürze (und hat einen möglichen Überlauf-Check).

Der Ort, das wird Sie am meisten weh tun die Schleife selbst, nicht das Array zugreift. Zum Beispiel nimmt diese unschuldig aussehende Schleife:

for (short i = 0; i < 32000; i++) {
    ...
}

Sieht gut aus, nicht wahr? Nee! Grundsätzlich können Sie die Initialisierung (short i = 0) ignorieren, da es nur einmal passiert, aber der Vergleich (i<32000) und Erhöhen (i++) Teile passieren 32.000 mal. Hier einig pesudo-Code für das, was dieses Ding sieht aus wie auf der Maschinenebene:

  Int16 i = 0;
LOOP:
  Int32 temp0 = Convert_I16_To_I32(i); // !!!
  if (temp0 >= 32000) goto END;
  ...
  Int32 temp1 = Convert_I16_To_I32(i); // !!!
  Int32 temp2 = temp1 + 1;
  i = Convert_I32_To_I16(temp2); // !!!
  goto LOOP;
END:

Es gibt 3 Conversions da drin, die ausgeführt werden 32000 Zeiten. Und sie vollständig durch nur mit einem Int32 oder Int64 hätte vermieden werden können.

Update: Wie ich im Kommentar gesagt, ich habe jetzt in der Tat eine Blog-Post zu diesem Thema geschrieben, . NET Integral-Datentypen und Sie

Int16 kann tatsächlich sein, weniger effizient, weil die x86-Befehle für Wort Zugriff mehr Platz einnehmen als die Anweisungen für dword Zugang. Es hängt davon ab, was der JIT tut. Aber egal was, es ist fast sicher nicht mehr effizient, wenn sie als die Variable in einer Iteration verwendet.

Das Gegenteil ist wahr.

32 (oder 64) Bit-Integer sind schneller als int16. Im Allgemeinen ist der nativen Datentyp ist die schnellste.

Int16 sind schön, wenn Sie Ihre Daten-Strukturen so schlank wie möglich machen wollen. Das spart Platz und kann die Leistung verbessern.

Jeder Performance-Unterschied wird so klein, auf moderne Hardware sein, die für alle Absichten und Zwecke, es wird keinen Unterschied machen. Versuchen Sie, ein paar Testbäume zu schreiben und laufen sie beide ein paar hundert Mal, nehmen Sie die durchschnittliche Schleifendurchlaufzeiten, und Sie werden sehen, was ich meine.

Es könnte sinnvoll von einem Speicher Perspektive, wenn Sie sehr begrenzte Ressourcen haben -. Embedded-Systeme mit einem kleinen Stapel, Draht Protokolle für langsame Netzwerke entwickelt (zum Beispiel GPRS, etc.), und so weiter

Nie Effizienz übernehmen.

Was ist oder nicht effizienter wird vom Compiler Compiler und Plattform zu Plattform variieren. Es sei denn, Sie tatsächlich getestet, es gibt keine Möglichkeit zu sagen, ob int16 oder int effizienter ist.

Ich würde nur mit ints bleiben, wenn Sie über eine bewährte Leistung Problem kommen, dass die Verwendung int16 Behebungen.

Verwenden Int32 auf 32-Bit-Maschinen (oder Int64 auf 64-Bit-Maschinen) für höchste Leistung. Verwenden Sie einen kleineren Integer-Typen, wenn Sie wirklich besorgt über den Raum es in Anspruch nimmt (möglicherweise langsamer, obwohl).

Die andere hier richtig sind, verwenden Sie nur weniger als Int32 (für 32-Bit-Code) / Int64 (für 64-Bit-Code), wenn Sie es für extreme Speicheranforderungen benötigen, oder für eine andere Ebene die Durchsetzung auf einem Business-Objektfeld (Sie sollten noch propery Ebene Validierung in diesem Fall natürlich haben).

Und im Allgemeinen, keine Sorge um Effizienz, bis ein Leistungsproblem ist. Und in diesem Fall das Profil zu. Und wenn guess & Prüfung mit beiden Möglichkeiten, während Profilierung Sie genug nicht hilft, den Code IL überprüfen.

Gute Frage though. Sie lernen mehr darüber, wie der Compiler tut es Sache. Wenn Sie wollen lernen, effizienter zu programmieren, die Grundlagen der IL lernen und wie die C # / VB-Compiler tun ihre Arbeit wäre eine gute Idee sein.

Ich kann nicht dort vorstellen, dass eine signifikante Leistungssteigerung auf Int16 vs. int.

Sie einige Bits in der Variablendeklaration speichern.

Und auf jeden Fall nicht der Mühe wert, wenn die Spezifikationen ändern und was auch immer Sie zählen können jetzt über 32767 gehen und Sie feststellen, dass, wenn die Anwendung beginnt Ausnahmen werfen ...

Es gibt keinen signifikanten Leistungszuwachs einen Datentyp kleiner als Int32 bei der Verwendung in der Tat, ich irgendwo gelesen, dass Int32 mit schneller als Int16 wegen Speicherzuweisung wird

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top