PInvoke from _wtof_l in C # is faster than initially referencing C ++

I wrote some high-performance code in C #, and I wanted to compare my implementation with my native C ++, since I called the msvcrt function many times. To my surprise, it seems that the C # version of the code is faster than its native version (!). Can anyone 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 the x86 Release with VS2017, and both were executed several times with VisualStudio turned off. Below are the results on my machine. As you can see, the C # version is about 30% faster:

enter image description here

- ? : Win32 ++ ConsoleApplication , ++ runtime ++, _wtof_l.

+4
1

0, . :

C#  x86: 520 msec
C#  x64: 395 msec 
C++ x86: 408 msec
C++ x64: 273 msec

. , 64- # 32- ++. , .

, , , wtof(). ++ , VS ( msvcrxxx.dll), msvcrt.dll. VS2015 . CRT VS2017 rtm, msvcrt.dll Win10.

, : pinvoke , 64- , , , 80% . YMMV.

+5

Source: https://habr.com/ru/post/1687087/


All Articles