Delphi 在DLL中调用函数太慢了

Delphi 在DLL中调用函数太慢了,delphi,dll,Delphi,Dll,我的程序有几个工作线程,它们在动态加载的DLL文件中调用函数。性能比在EXE文件中调用函数慢。我的程序是用Delphi编写的。我不使用sharem。DLL中的函数有许多将文件读入内存的例程。使用的调用约定是stdcall。实际上,速度很差 我不知道,因为我刚刚学会了使用DLL。那么,我应该如何优化程序/DLL的性能/速度呢 对不起,如果我的问题没有意义。我确信我的exe没有问题,我只是把我的函数移到了DLL中,性能会变慢。请忽略磁盘/内存缓存因素,因为我已经提到了我的DLL例程 编辑: 这就是我

我的程序有几个工作线程,它们在动态加载的DLL文件中调用函数。性能比在EXE文件中调用函数慢。我的程序是用Delphi编写的。我不使用sharem。DLL中的函数有许多将文件读入内存的例程。使用的调用约定是stdcall。实际上,速度很差

我不知道,因为我刚刚学会了使用DLL。那么,我应该如何优化程序/DLL的性能/速度呢

对不起,如果我的问题没有意义。我确信我的exe没有问题,我只是把我的函数移到了DLL中,性能会变慢。请忽略磁盘/内存缓存因素,因为我已经提到了我的DLL例程

编辑:

这就是我的程序加载DLL的方式

  DLLHandle := LoadLibrary(pwchar(path));
  if DLLHandle <> 0 then
  @CheckFile := GetProcAddress(DLLHandle, 'CheckFile');
现在,DLL中的代码

function CheckFile(const FileName: string; var FileType: WideString)
  : boolean; stdcall;
var
  testCheckFile: TBla;
begin
  Result := false;
  testCheckFile  := TBla.Create;
  try
    if testCheckFile.DoSomeRoutine(FileName, FileType) then
      Result := true;
  finally
    testCheckFile.Free;
  end;
end;
exports CheckFile;

begin
IsMultiThread := true;
end.
我的DLL做什么?它可以像将文件转换为指针一样使用TFileStream


我希望我的加载代码和调用代码有问题。

问题可能与“动态加载的DLL文件”有关。动态是可以的,但一旦你加载它,保持它加载正确吗?如果继续为每个函数调用加载/卸载,则速度会很慢(在调试器中会慢得多!)

驻留在DLL中的代码与驻留在主机可执行文件中的代码以相同的速度运行。将代码移动到DLL中极不可能导致性能明显下降

但是,您在对问题的评论中声明,您还将从Delphi 2007移植到Delphi XE2。这几乎可以肯定是导致性能下降的变化


在衡量和比较性能时,一次只改变一件事是非常重要的,这样可以消除任何混杂因素的可能性。

如果没有任何信息,这是不可能的,但没有理由认为DLL中的代码应该很慢。代码就是代码。不管你把它放在哪里,你绝对没有提供任何我们可以用来帮助你的信息。如果没有任何类型的代码,没有关于函数实际功能的任何信息(“DLL中的函数有许多将文件读入内存的例程”没有提供任何有用的信息),并且“性能比调用EXE中的函数慢”也没有提供任何帮助。请记住,除了您在问题中提供的信息外,我们对您的问题(或代码)一无所知;我们看不到你的屏幕,也看不懂你的心思。请编辑您的帖子以提供更多详细信息,否则很可能会以“非真实问题”结束。顺便说一句,不要在模块边界上使用
字符串。它不是有效的互操作数据类型。您可以在不同的堆上进行分配和释放。另外,所有模块都需要使用相同的编译器。当然,不要考虑跨模块边界发送对象。在这里的函数中,
WideString
PChar
是您应该使用的。@CharlesSungkono不,如果您每次调用DLL函数时都调用GetProcAddress,您会遇到问题。但既然你不知道,那就没问题了。我不相信你的代码在DLL中会慢一些。也许您使用debug而不是release来构建它。也许在DLL中有范围检查,但在EXE中没有。可能DLL中的代码与EXE中的代码不同。不管区别是什么,都不会是代码在DLL中运行的事实,否则我会吃我的帽子。当然Unicode可以带来不同。很容易得到花费大量时间在ANSI和UTF16之间转换的代码。或者,可能只是瓶颈上的数据流量增加了一倍。港口显然是这里的候选者。在DLL中调用代码的解释真是难以置信。这不是答案;这是另一条评论,应该以这样的方式发布。事实并非如此。Windows有这样的机制来避免这种问题。首先,当您告诉windows卸载dll时,它不会卸载dll。当它决定这是一个很好的时间去做的时候,它就会这样做。实际上,一旦你将dll加载到内存中,不管你是否调用freelibrary,windows都会一直加载它,直到你的程序关闭。你可以自己测试。只需加载dll并查看句柄。卸下它们,然后重新加载。然后比较手柄。它应该是平等的。正因为如此,而且你没有回答这个问题,我给你-1。@RafaelColucci试试基准测试
lib:=LoadLibrary('mydll.dll');免费图书馆在一个紧密的循环中,看看你每秒能做多少次。@RafaelColucci你的评论是错误的。
LoadLibrary
@David的开销很大。这没有道理。我很确定这不会减缓循环。当然,你应该对苹果进行比较。你在做什么来比较结果?只有一个循环不做任何事情的代码和一个使用加载和释放库的循环的代码?在这种情况下,结果当然会有所不同,因为不执行任何操作的循环将被优化,并且根本不会被编译器执行。请给我一个更好的例子。我想如果我使用最新的编译器,结果会更快。我的程序工作正常(搜索文件和检查文件),但性能变慢。我刚刚做了一个简单的测试,比较了我在程序中使用的uSimpleTrustCheck(你可以用谷歌搜索)函数的执行时间。格式:编译器|第一次测试|第二次测试|第三次测试。DXE:50937.91µs | 45894.93µs | 46083.98µs。D2007:18259.59µs | 26364.67µs | 22770.57µs。这只是一个简单的函数,我在程序中使用了另一个函数:(@Charles取决于你的函数在做什么。看起来很明显,DLL不是问题所在。
function CheckFile(const FileName: string; var FileType: WideString)
  : boolean; stdcall;
var
  testCheckFile: TBla;
begin
  Result := false;
  testCheckFile  := TBla.Create;
  try
    if testCheckFile.DoSomeRoutine(FileName, FileType) then
      Result := true;
  finally
    testCheckFile.Free;
  end;
end;
exports CheckFile;

begin
IsMultiThread := true;
end.