我们正在将工作站从Win7升级到Win10。在调查性能下降的报告时,我得出的结论是它是由第三方安装的WH_CALLWNDPROC挂钩引起的。
我是基于以下测试应用程序的结果(在Delphi 10 Seattle中完成)得出的结论
procedure TForm3.Button1Click(Sender: TObject);
var
I: Integer;
SW : TStopWatch;
begin
sw := TStopWatch.StartNew;
for I := 0 to 1000000 do
begin
if Combobox1.ItemIndex > 0 then
Exit;
end;
sw.Stop;
ShowMessage(sw.ElapsedMilliseconds.ToString);
end;
(对于那些不熟悉Delphi的人,TStopwatch使用QueryPerformanceFrequency / QueryPerformanceCounter API来获取经过的时间)
此方法的执行时间为
(注意:两台机器的硬件完全不同,因此无法真正比拟。)
现在,如果我在执行相同代码之前添加钩子
function MySystemWndProcHook(Code: Integer; wParam: WParam; lParam: LParam): LRESULT; stdcall;
begin
Result := CallNextHookEx(FHook, Code, wParam, LParam);
end;
procedure TForm3.FormCreate(Sender: TObject);
begin
FHook := SetWindowsHookEx(WH_CALLWNDPROC, @MySystemWndProcHook, 0, GetCurrentThreadId)
end;
执行时间变为:
现在,正如我所提到的,两个工作站都在不同的硬件上,但是我不相信仅凭这一个就可以解释两者之间的差异。 Win10具有i7 cpu,而Win7具有i3。如果有的话,我希望i3受到更大的冲击(更少的缓存,更少的资源...)
那么,自Win7以来,WH_CALLWNDPROC挂钩的速度变慢了这么多吗? 快速的Google搜索似乎没有发现有关此问题的任何其他报告。有人可以复制我的结果吗? 如果无法复制它,那么任何人都不知道是什么设置/冲突的应用程序引起的? (已经尝试禁用Windows Defender实时扫描,但这并不影响性能。)
编辑:这已在Win10 1803 64位下进行了测试。测试应用程序本身是32位。
EDIT2:用64位编译的同一应用程序具有以下执行时间。
EDIT3:有趣的是,以admin身份运行应用程序(32位)时:
(在另一个工作站上),以不同用户身份运行也会有所不同:
EDIT4:如果以管理员身份运行,则从USB密钥运行的应用程序比从硬盘运行的速度更快。 (注意:到目前为止,我仅在具有单个驱动器的系统上进行了测试。在这一点上,我不排除仅OS驱动器的速度较慢。)
EDIT5:我发现了很多有关这种情况的事情。 首先,运行“以管理员身份”(win10)会使应用程序安装WH_CALLWNDPROCRET挂钩。我还没有找到它的来源(操作系统,Delphi的框架,其他应用程序?)。仅仅运行该应用程序绝对不存在。
对性能的影响似乎并没有那么多,而是对SendMessage的影响。
我们正在与Microsoft保持联系,他们再现了类似的结果(在100k循环而不是1m的循环中):
(调查仍在进行中,到目前为止尚无结论)
这些结果还表明,我们的许多工作站的性能都比不涉及钩子时的性能差。
答案 0 :(得分:1)
因此,WH_CALLWNDPROC和WH_CALLWNDPROCRET挂钩确实会大大降低性能。与Win7相比,Win10中的优势更多。
一些性能上的损失来自Spectre和Meltdown的缓解代码。微软的早期报告表明,其余的显然来自窗口管理器(win32k * .sys)中的锁争用。
对于我在调查中得到的奇怪结果: