Мы находимся в процессе обновления наших рабочих станций до Win10 с Win7.Исследуя сообщения о снижении производительности, я пришел к выводу, что это было вызвано хуком WH_CALLWNDPROC, установленным третьей стороной.
Я пришел к такому выводу на основе результата следующего тестового приложения (сделано в Delphi 10Сиэтл)
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 использует API QueryPerformanceFrequency / QueryPerformanceCounter для получения истекшего времени)
Время выполнения для этого метода составляет
- Win10: 1485 мсек
- Win7: 4996 мсек
(Примечание. Обе машины работают на совершенно разных аппаратных средствах и их нельзя сравнивать с другими).
Теперь, если я добавлю ловушку перед выполнением того же кода
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: 19552 мсек (примерно на 1300% больше)
- Win7: 8682 мсек (примерно на 75% больше)
Теперь, как я уже упоминал, обе рабочие станции работают на разных аппаратных средствах, но я не верю, что одна можетобъяснить разницу.Win10 имеет процессор i7, а Win7 - i3.Во всяком случае, я бы ожидал, что i3 получит больший удар (меньше кеша, меньше ресурсов ...)
Итак, хуки WH_CALLWNDPROC стали намного медленнее, чем Win7?Быстрый поиск в Google, похоже, не выявил никаких других сообщений об этой проблеме.Кто-нибудь может воспроизвести мои результаты?Если это не может быть воспроизведено, кто-нибудь знает, какие настройки / конфликтующие приложения могут быть причиной этого?(Уже пытался отключить проверку в режиме реального времени Защитником Windows, и это не повлияло на производительность.)
РЕДАКТИРОВАТЬ: Это было протестировано под Win10 1803 64 бит.Само тестовое приложение имело 32 бита.
EDIT2: то же приложение, скомпилированное в 64 бита, дает следующее время выполнения.
- Win10: 780 мсек / 10201 мсек.
- Win7: 6419 мсек / 9201 мсек.
EDIT3: Интересно, что при запуске приложения (32bit) от имени администратора:
- Win10: 12693 мсек / 18028 мсек
Кроме того, (на еще одной рабочей станции) работа другого пользователя имеет значение:
- Win10 (1809) / «обычный пользователь»: 9430/17440 мсек
- Win10 (1809) / система: 5220/10160 мсек (запущен удаленно через PsExec)
EDIT4: при запуске от имени администратора приложение будет работать быстрее с USB-ключа, чем с жесткого диска.(Примечание. До сих пор я тестировал только систему с одним диском. На этом этапе я не исключаю, что только диск с ОС работает медленнее.)
РЕДАКТИРОВАТЬ5: Я обнаружил еще несколько вещейоб этой ситуации.Во-первых, запуск «As Admin» (win10) приводит к тому, что в приложении устанавливается хук WH_CALLWNDPROCRET.Я не нашел, откуда это (ОС, платформа Delphi, другое приложение?).Это определенно не при простом запуске приложения.
Кажется, что снижение производительности не сильно влияет на саму ловушку, а влияет на SendMessage.
Мы в контактепри поддержке Microsoft они воспроизводили аналогичные результаты (по циклу 100 КБ вместо 1 м):
- Windows 7 - без перехвата 0,018396 секунд.
- Windows 10 - без перехвата 0,025102 секунды.
- Windows 7 - с крюком 0,167941 секунды.
- Windows 10 - с крюком 1,105929 секунды.
(Расследование еще не завершено, поэтому пока нет никаких выводов)
Эти результаты также свидетельствуют о том, что многие из наших рабочих станций работают намного хуже, чем должны, когда не используются зацепки.