I was writing some high performance code in C# and I wanted to compare my implementation to native C++ one, as I was pinvoking msvcrt function a lot. To my suprise it appears that C# version of the code is faster than it's native version (!). Can someone explain this behavior?
C# version:
using System.Diagnostics;
using System.Security;
using System.Runtime.InteropServices;
class Program
{
[DllImport("msvcrt.dll", EntryPoint = "_wtof_l", CallingConvention = CallingConvention.Cdecl)]
[SuppressUnmanagedCodeSecurity]
private extern unsafe static double _wtof_l(char* str, IntPtr locale);
[DllImport("msvcrt.dll", EntryPoint = "_create_locale", CallingConvention = CallingConvention.Cdecl)]
private extern static IntPtr CreateLocale(int category, string locale);
private const int LC_NUMERIC = 4;
static unsafe void Main(string[] args)
{
var locale = CreateLocale(LC_NUMERIC, "C");
fixed (char* test = "1.2")
{
int x = 10;
while (x-- > 0)
{
var sw = Stopwatch.StartNew();
double sum = 0;
for (int i = 0; i < 10_000_000; i++)
{
sum += _wtof_l(test, locale);
}
Console.WriteLine(sum + " " + sw.ElapsedMilliseconds);
}
}
Console.ReadLine();
}
}
C++ version:
#include <locale.h>
#include <stdio.h>
#include <chrono>
#include <string>
#include <iostream>
int main()
{
auto test = L"1.2";
_locale_t locale = _create_locale(LC_NUMERIC, "C");
int x = 10;
while (x--)
{
auto start = std::chrono::high_resolution_clock::now();
double sum = 0;
for (int i = 0; i < 10000000; i++)
{
sum += _wtof_l(test, locale);
}
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff = end - start;
std::cout << sum << " " << diff.count() << std::endl;
}
std::getline(std::cin, std::string());
return 0;
}
Both applications were compiled on x86 Release with VS2017, and both were run multiple times with VisualStudio turned off. Below are results on my machine. As you can see, C# version is faster by about 30%:
Can someone explain this confusing behavior? My guess would be either: Some optimizations are not turned on in default Win32 C++ ConsoleApplication project, or C++ runtime does some initialization code in C++ application that slows down invocations of _wtof_l.
