Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient alternative to using Managed API in C#?

Tags:

c#

import

dll

So if I directly use kernel32 to delete my file as an example, would it be more efficient alternative to this C# API?

System.IO.File.Delete(string Path);

If I import the dll like so and just use DeleteFile("C:.."):

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool DeleteFile([MarshalAs(UnmanagedType.LPWStr)]string lpFileName);

Will it be better in effeciency e.g Time it takes to execute the code?

like image 911
K_X Avatar asked Jan 27 '26 04:01

K_X


2 Answers

It is a fairly common misconception that managed code is slow. In general it is not, you execute the same kind of code that a C compiler produces, machine code. It is especially not relevant with a large number of the kind of .Net framework classes that are wrappers for operating system functions.

Like the File class. The File.Delete() method in fact pinvokes the DeleteFile() winapi function. Necessarily so, that's the only way to delete a file on Windows. There is nothing the .NET framework could do, at least not until a managed operating system becomes available. Which may actually happen some day, the super-secret Midori project at Microsoft aims to develop just such an operating system.

But that's future-music, right now it is a big chunk of C code, buried in a file system driver like Fat32 or NTFS that actually gets the job done. It operates at disk speeds, DeleteFile() doesn't return until the file system driver confirmed that the deletion is completed. Which is very, very slow. Like around 50 milliseconds for an old-fashioned hard drive, in the sub-millisecond range for an SSD.

File.Delete() does add code, it performs lots of error checking. If verifies that the argument you pass isn't null, checks if your code isn't running in a sandbox that denies file deletion right, checks if you didn't specify any characters in the path that are not legal in a file path, converts an incremental path to a full path and checks that it is still a legal path, checks if the path string isn't too long, converts short MS-Dos 8.3 names to long names if necessary.

That's a bunch of work but that's measured in microseconds. If you pinvoke DeleteFile then you'll skip that code but you'll only make it ~1% faster, at best. What you'll lose is reliability, the guarantee that if you have an oops in your code or data that you are going to be told about it. With a very clear exception message that tells you exactly what is wrong. Extremely valuable because those few microseconds multiplied by a billion is still no match for the amount of time and suffering you'll expend on debugging a DeleteFile() that didn't work.

Don't do it.

like image 79
Hans Passant Avatar answered Jan 29 '26 19:01

Hans Passant


The only way to know for sure is to test it. Write code that creates a whole bunch of temp files, and then time how long it takes to delete them all.

The performance considerations here:

  • any possible performance gain from using the native api for file deletion (kernel32) vs
  • the performance loss from having to use marshalling.

It would be my hunch that any performance gain would be minor, if you were to get one at all.

like image 33
Fabian Tamp Avatar answered Jan 29 '26 18:01

Fabian Tamp