Dll函数调用比普通函数调用更快吗?

5

我正在测试一个DLL中导出函数和普通函数的速度。为什么导出函数比普通函数快得多呢?

100000000 function calls in a DLL cost: 0.572682 seconds
100000000 normal function class cost: 2.75258 seconds

这是动态链接库中的函数:

extern "C" __declspec (dllexport) int example()
{
    return 1;
}

这是普通的函数调用:

int example()
{
    return 1;
}

这是我测试它的方法:
int main()
{
    LARGE_INTEGER frequention;
    LARGE_INTEGER dllCallStart,dllCallStop;
    LARGE_INTEGER normalStart,normalStop;
    int resultCalculation;

    //Initialize the Timer
    ::QueryPerformanceFrequency(&frequention);
    double frequency = frequention.QuadPart;
    double secondsElapsedDll = 0;
    double secondsElapsedNormal = 0;

    //Load the Dll
    HINSTANCE hDll = LoadLibraryA("example.dll");

    if(!hDll)
    {
        cout << "Dll error!" << endl;
        return 0;
    }

    dllFunction = (testFunction)GetProcAddress(hDll, "example");

    if( !dllFunction )
    {
        cout << "Dll function error!" << endl;
        return 0;
    }

    //Dll
    resultCalculation = 0;
    ::QueryPerformanceCounter(&dllCallStart);
    for(int i = 0; i < 100000000; i++)
        resultCalculation += dllFunction();
    ::QueryPerformanceCounter(&dllCallStop);

    Sleep(100);

    //Normal
    resultCalculation = 0;
    ::QueryPerformanceCounter(&normalStart);
    for(int i = 0; i < 100000000; i++)
        resultCalculation += example();
    ::QueryPerformanceCounter(&normalStop);

    //Calculate the result time
    secondsElapsedDll = ((dllCallStop.QuadPart - dllCallStart.QuadPart) / frequency);
    secondsElapsedNormal = ((normalStop.QuadPart - normalStart.QuadPart) / frequency);

    //Output
    cout << "Dll: " << secondsElapsedDll << endl; //0.572682
    cout << "Normal: " << secondsElapsedNormal << endl; //2.75258

    return 0;
}

我只测试函数调用速度,获取地址可以在启动时完成。因此,这样做的性能损失并不重要。


1
我不相信那是因为“这个”普通函数将被内联,但来自 DLL 的函数不能被内联。所以我认为你必须在做一些不恰当的事情。你是否使用发布版本构建? - Nawaz
1
你是如何编译这两个项目的?某些优化选项可能会决定不调用该函数,这样会更快。 - Yochai Timmer
4
为了好玩,将 int resultCalculation; 改为 volatile int resultCalculation; ,然后重新运行测试。同时交换顺序(先运行本地程序,然后再运行 DLL)。 - WhozCraig
@WhozCraig 这是结果:http://pastebin.com/riZV4X0j 现在我看到了这会带来多少开销。 - Laurence
@WhozCraig 准备测试一下。 - Laurence
显示剩余13条评论
1个回答

8

对于一个非常小的函数来说,区别在于函数返回/清理参数的方式。

然而,这不应该有太大的影响。我认为编译器会意识到你的函数没有对 resultCalculation 进行任何操作并将其优化掉。尝试使用两个不同的变量,并在之后打印它们的值。


优化确实是问题所在。当我将 int resultCalculation; 替换为 volatile int resultCalculation; 时,普通调用速度更快。(感谢 @WhozCraig 提供的建议。) - Laurence

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接