Frage

Kann jemand ein Beispiel für eine gute Zeit, um tatsächlich „unsicher“ und „fixed“ in C # -Code zu verwenden? Ich habe vor mit ihm gespielt, aber nie gefunden eigentlich eine gute Verwendung für sie.

Mit diesem Code Betrachten ...

fixed (byte* pSrc = src, pDst = dst) {
    //Code that copies the bytes in a loop
}

im Vergleich zu einfach mit ...

Array.Copy(source, target, source.Length);

Der zweite ist der Code in .NET Framework, der erste Teil der von der Microsoft-Website kopierten Code gefunden, http://msdn.microsoft.com/en-us/library/28k1s2k6 (VS.80) aspx .

Die in Array.Copy gebaut () ist dramatisch schneller als Unsafe Code. Dies könnte nur weil der zweite ist einfach besser geschrieben und die erste ist nur ein Beispiel, aber welche Arten von Situationen würden Sie wirklich noch Unsichere / Fest Code für etwas verwenden? Oder ist dies ein schlechter Web-Entwickler mit etwas über seinem Kopf durcheinander?

War es hilfreich?

Lösung

Es ist nützlich für das Interop mit nicht verwalteten Code. Alle Hinweise auf nicht verwalteten Funktionen übergeben müssen festgelegt werden (aka. Gepinnt) die Garbage Collector zu verhindern, dass der zugrunde liegenden Speicher verlagern.

Wenn Sie P verwenden / Invoke, dann wird die Standard-Einweiser Objekte für Sie Pin. Manchmal ist es notwendig, benutzerdefinierte Rangierung durchzuführen, und manchmal ist es notwendig, ein Objekt länger als die Dauer eines einzelnen P / Invoke Aufruf an Pin.

Andere Tipps

Ich habe unsichere-Blöcke verwendet Bitmap-Daten zu manipulieren. Rohzeiger-Zugang ist deutlich schneller als SetPixel / GetPixel.

unsafe
{
    BitmapData bmData = bm.LockBits(...)
    byte *bits = (byte*)pixels.ToPointer();
    // Do stuff with bits
}

„fixiert“ und „unsicher“ verwendet wird in der Regel bei der Interop tun, oder wenn zusätzliche Leistung benötigt wird. D. h. String.CopyTo () verwendet unsicher und in seiner Durchführung fixiert.

reinterpret_cast Stil Verhalten

Wenn Sie etwas manipulieren kann dies unglaublich nützlich sein

viele Hochleistungs-Hash-Code-Implementierungen verwenden UInt32 für den Hash-Wert (das die Verschiebungen einfacher macht). Da .Net Int32 für das Verfahren erfordert möchten Sie schnell die uint in einen int konvertieren. Da es spielt keine Rolle, was der tatsächliche Wert ist, nur, dass alle Bits im Wert ein reinterpret Guss erhalten sind erwünscht ist.

public static unsafe int UInt32ToInt32Bits(uint x)
{
    return *((int*)(void*)&x);
}

Beachten Sie, dass die Namensgebung auf der BitConverter.DoubleToInt64Bits

in der Hashing-Vene fort, einen Stapel basierte Struktur in eine Byte-Umwandlung * ermöglicht die einfache Verwendung von pro Byte Hashing-Funktionen:

// from the Jenkins one at a time hash function
private static unsafe void Hash(byte* data, int len, ref uint hash)
{
    for (int i = 0; i < len; i++)
    {
        hash += data[i];
        hash += (hash << 10);
        hash ^= (hash >> 6);
    }
}

public unsafe static void HashCombine(ref uint sofar, long data)
{
    byte* dataBytes = (byte*)(void*)&data;
    AddToHash(dataBytes, sizeof(long), ref sofar);
}

unsichere auch (ab 2.0) können Sie verwenden stackalloc. Dies kann in Hochleistungs Situationen sehr nützlich sein, wenn einige kleine variabler Länge Array wie temporären Speicherplatz benötigt wird.

Alle diese Anwendungen würden fest in der sein ‚nur dann, wenn Ihre Anwendung wirklich braucht, um die Leistung‘ und damit ungeeignet sind im allgemeinen Gebrauch, aber manchmal wirklich Sie brauchen.

festgelegt ist notwendig, wenn Sie mit einigen nützlichen nicht verwalteten Funktion Interop wollen (es gibt viele), die c-style-Arrays oder Strings nimmt. Als solches ist es nicht nur aus Leistungsgründen aber Korrektheit diejenigen wenn in Interop-Szenarien.

Unsichere nützlich ist für (zum Beispiel) erhalten Pixeldaten aus einem Bild unter Verwendung LockBits schnell. Die Leistungsverbesserung gegenüber tun dies die verwaltete API ist um mehrere Größenordnungen.

Wir hatten eine feste zu verwenden, wenn eine Adresse zu einem Legacy-C-DLL übergeben wird. Da die DLL einen internen Zeiger über Funktionsaufrufe beibehalten, würde die Hölle losbrechen, wenn der GC den Haufen verdichtet und bewegt Sachen herum.

Ich glaube, unsicheren Code verwendet, wenn Sie etwas außerhalb der .NET-Laufzeit, also zugreifen möchten. es ist nicht Code (keine Müllabfuhr usw.) verwaltet. Dazu gehören rohe Aufrufe an die Windows-API und alle, die Jazz.

Das sagt mir die Designer der .NET-Frameworks gute Arbeit geleistet hat, das Problem Raum abdeckt - von sicherstellen, dass die Umwelt „Managed Code“ alles kann ein traditioneller (zB C ++) Ansatz mit seinem unsicheren Code tun / Zeiger. Für den Fall, kann es nicht, sind die unsicheren / Fest Funktionen dort, wenn Sie sie benötigen. Ich bin sicher, dass jemand ein Beispiel hat in dem unsicheren Code benötigt wird, aber es scheint in der Praxis selten - was eher der Punkt ist, ist es nicht? :)

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