A very long time ago, maybe it was even as much as 2 years ago now, I wanted to answer the question 'Just how much overhead is there using one API call compared to another API call?'. This question came to mind after I realized just how many ways there was to move a file. So I wrote a simple command line application to track just that.
The application moved a file back and fourth 5000 times using a certain method, and I recorded the results' averages(excluding times when the disk cache caused really bad results):
Well there is a lot of overhead in just the functions calling other functions further up the chain, and converting the text to unicode in some cases. If I had to take a guess, the call stack would look something like this from the slowest method:
Part of the source code was written by Alex Ionescu and I have removed a few parts of the code because it used undocumented behavior in the 'Fastest' method. This code was compiled without optimization(turning them on may even fix this problem for you) using the mingw compiler.
CALLBACKWinMain(__in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd){ MSG Msg; int i; DWORD Start, End; Start = GetTickCount(); for(i = 0; i < 5000; i++) {#ifdef SLOWEST rename("C:\\Temp\\foo.exe","C:\\Temp\\bar.exe"); rename("C:\\Temp\\bar.exe","C:\\Temp\\foo.exe");#endif /* SLOWEST */ #ifdef SLOW MoveFileA("C:\\Temp\\foo.exe","C:\\Temp\\bar.exe"); MoveFileA("C:\\Temp\\bar.exe","C:\\Temp\\foo.exe");#endif /* SLOW */ #ifdef FAST MoveFileWithProgressW(L"C:\\Temp\\foo.exe",L"C:\\Temp\\bar.exe", NULL, NULL, MOVEFILE_COPY_ALLOWED); MoveFileWithProgressW(L"C:\\Temp\\bar.exe",L"C:\\Temp\\foo.exe", NULL, NULL, MOVEFILE_COPY_ALLOWED);#endif /* FAST */ #ifdef FASTEST { // Shared Variables NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; HANDLE Handle; // Open the old file and tell NT we plan to delete it Status = NtOpenFile(/* Remove */); // Do the first rename Status = NtSetInformationFile(/* Remove */); // Close the handle NtClose(Handle); // Open the new file and tell NT we plan to delete it Status = NtOpenFile(/* Remove */); // Do the 2nd rename Status = NtSetInformationFile(/* Remove */); NtClose(Handle); }#endif /* FASTEST */ } End = GetTickCount(); printf("%d -- %d\n",(End - Start),GetLastError()); system("pause"); return 0; }