What is the advantage of using unsafe and secure C # code?

unsafe static void SquarePtrParam (int* p) { *p *= *p; } 

VS

 static void SquarePtrParam (ref int p) { p *= p; } 
+8
c # unsafe
source share
5 answers

Safe code can work in any situation where you can run C # code (Silverlight, shared hosting ASP.NET, XNA, SQL Server, etc.), and insecure code requires increased trust. This means that you can run your code in more places and with less restrictions.

In addition, it is safe, which means that you do not need to worry that you are doing something wrong and the failure of your process.

+10
source share

Your example is not very good, the JIT compiler already generates such code. Signs are also indicated under the hood. It had to be fast, managed code would never be competitive.

Garbage collected in a heap is quite incompatible with pointers, you need to attach objects so that you can create a pointer to them. Without fixing, the garbage collector could move the object, and your code accidentally failed, destroying the integrity of the heap. Pinning has a non-zero cost, both in operation and in case of loss of efficiency that you will suffer, and also after you release it, when garbage collection occurs, when the object is fixed.

Pointers are very efficient when accessing unmanaged memory. A canonical example is image processing, which requires access to the pixels of a raster image. And this is a way to quickly access pinned arrays with the removal of all security locks, checking the index of the array is not free if you do not iterate over them.

+7
source share

There is only one reason to use unsafe code: Initial performance.

Using unsafe code, you can use C ++ as pointers, without much control over runtime. No checks mean you are on your own, but there is less overhead.

I just saw it in action to speed up image / bitmap manipulation. But you can also use it for inline string manipulations (yes, making strings mutable !!! Bad idea if you don't want to build a StringBuilder). Other applications include matrix computing or other heavy math. And they probably interact with the OS and some hacks.

+5
source share

A great example is described in J.Richter's "CLR via C #", 3 edition, Ch. 16: The following C # code demonstrates three methods (safe, jagged, and unsafe) to access a two-dimensional array:

 using System; using System.Diagnostics; public static class Program { private const Int32 c_numElements = 10000; public static void Main() { const Int32 testCount = 10; Stopwatch sw; // Declare a two-dimensional array Int32[,] a2Dim = new Int32[c_numElements, c_numElements]; // Declare a two-dimensional array as a jagged array (a vector of vectors) Int32[][] aJagged = new Int32[c_numElements][]; for (Int32 x = 0; x < c_numElements; x++) aJagged[x] = new Int32[c_numElements]; // 1: Access all elements of the array using the usual, safe technique sw = Stopwatch.StartNew(); for (Int32 test = 0; test < testCount; test++) Safe2DimArrayAccess(a2Dim); Console.WriteLine("{0}: Safe2DimArrayAccess", sw.Elapsed); // 2: Access all elements of the array using the jagged array technique sw = Stopwatch.StartNew(); for (Int32 test = 0; test < testCount; test++) SafeJaggedArrayAccess(aJagged); Console.WriteLine("{0}: SafeJaggedArrayAccess", sw.Elapsed); // 3: Access all elements of the array using the unsafe technique sw = Stopwatch.StartNew(); for (Int32 test = 0; test < testCount; test++) Unsafe2DimArrayAccess(a2Dim); Console.WriteLine("{0}: Unsafe2DimArrayAccess", sw.Elapsed); Console.ReadLine(); } private static Int32 Safe2DimArrayAccess(Int32[,] a) { Int32 sum = 0; for (Int32 x = 0; x < c_numElements; x++) { for (Int32 y = 0; y < c_numElements; y++) { sum += a[x, y]; } } return sum; } private static Int32 SafeJaggedArrayAccess(Int32[][] a) { Int32 sum = 0; for (Int32 x = 0; x < c_numElements; x++) { for (Int32 y = 0; y < c_numElements; y++) { sum += a[x][y]; } } return sum; } private static unsafe Int32 Unsafe2DimArrayAccess(Int32[,] a) { Int32 sum = 0; fixed (Int32* pi = a) { for (Int32 x = 0; x < c_numElements; x++) { Int32 baseOfDim = x * c_numElements; for (Int32 y = 0; y < c_numElements; y++) { sum += pi[baseOfDim + y]; } } } return sum; } } 

The Unsafe2DimArrayAccess method is marked with an unsafe modifier, which requires the use of a fixed C # operator. To compile this code, you need to specify the / unsafe option when invoking the C # compiler or select the "Allow unsafe code" checkbox on the "Assembly" tab in the "Project Properties" panel in Microsoft Visual Studio. When I run this program on my machine, I get the following output:

 00:00:02.0017692: Safe2DimArrayAccess 00:00:01.5197844: SafeJaggedArrayAccess 00:00:01.7343436: Unsafe2DimArrayAccess 

As you can see, the safe two-dimensional array access technique is the slowest. The technique of safely handling an uneven array takes a little less time to complete than a secure two-dimensional array access technology. However, you should note that creating a jagged array takes longer than creating a multidimensional array, because creating an jagged array requires the object to be allocated on the heap for each dimension, causing the garbage collector to periodically kick. So, there is a trade-off: if you need to create many “multidimensional arrays” and you intend to access elements rarely, it’s faster to create a multidimensional array. If you need to create a "multidimensional array" only once, and you often look at its elements, a jagged array will give you better performance. Of course, in most applications the latter scenario is more common.

+2
source share

I don’t think there is an advantage to using unsafe code in the example you provided. I really used unsafe code when I needed to interact with unmanaged code, for example, when calling interfaces without com-dll.

+1
source share

All Articles