Bug 3031

Summary: 1C77: Нужно оптимизировать скорость выполнения отчетов/расчетов
Product: WINE@Etersoft Reporter: Денис Баранов <baraka>
Component: ОбщееAssignee: Andrey Vusik <night>
Status: CLOSED FIXED QA Contact:
Severity: major    
Priority: P3 CC: borovinin, kondratyuk, lav, shpigor, vitperov
Version: 1.0.9Keywords: ИНТЕРРА
Target Milestone: ---   
Hardware: PC   
OS: All   
Whiteboard:
Заявки RT: 13129 Связано с:
Дата напоминания:
Bug Depends on: 3060, 3595    
Bug Blocks: 5906, 42    
Deadline: 2012-02-17   
Attachments: Таблица с рейтингом функций

Description Денис Баранов 2008-11-28 21:13:54 MSK
Есть тестовая база /ftp/pvt/Windows/1C/1Cv77_configs/Cntuik_2007_.tar.bz2, так же есть на cellar в sharewine. Там при вызове номенклатуры идет постоянный перерасчет итогов. 
На винде он выполняется секунд 5-9, а в wine секунд 30.
Comment 1 Vitaly Lipatov 2008-11-28 22:01:58 MSK
Получена статистика по количеству вызовов функций при пересчёте итогов при входе в окно списка номенклатуры:
   888 - gdi32.SetTextAlign
   888 - KERNEL32.lstrcpynA
   913 - KERNEL32.SetLastError
   918 - KERNEL32.GetLastError
   925 - KERNEL32.FindResourceA
   994 - user32.GetMessageA
  1006 - gdi32.ExtTextOutA
  1011 - gdi32.CreateSolidBrush
  1154 - user32.ScreenToClient
  1267 - user32.ModifyMenuA
  1390 - user32.PeekMessageA
  1589 - gdi32.SetBkColor
  1678 - gdi32.SetTextColor
  1686 - user32.AppendMenuA
  1745 - gdi32.DeleteObject
  1762 - user32.GetWindowRect
  1783 - user32.EnableMenuItem
  1805 - user32.GetClientRect
  1861 - user32.GetKeyState
  1873 - dialog
  2047 - user32.GetSysColor
  2065 - user32.InflateRect
  2069 - gdi32.SelectObject
  2153 - user32.PtInRect
  2293 - user32.CopyRect
  2441 - user32.OffsetRect
  2614 - KERNEL32.lstrcmpA
  2799 - user32.GetMenuItemCount
  3045 - user32.GetMenuState
  3260 - user32.GetWindowLongW
  3280 - user32.IsWindowVisible
  3788 - user32.GetDlgItem
  4658 - KERNEL32.GetTickCount
  4762 - user32.IsWindow
  6480 - user32.FillRect
  7525 - KERNEL32.WideCharToMultiByte
  8057 - ntdll.RtlFreeHeap
  8566 - ntdll.RtlAllocateHeap
  8669 - user32.SendMessageA
  9198 - user32.DefWindowProcA
  9977 - user32.IsCharAlphaA
 11756 - user32.IsChild
 13661 - user32.GetMenuItemID
 14579 - user32.GetFocus
 15020 - KERNEL32.LCMapStringW
 15140 - KERNEL32.MultiByteToWideChar
 16221 - user32.GetDlgCtrlID
 18835 - user32.CharUpperA
 20709 - user32.GetMenuStringA
 25275 - user32.GetWindowLongA
 32369 - user32.GetTopWindow
 40342 - user32.CallWindowProcA
 55601 - user32.IsCharAlphaNumericA
 62849 - user32.GetWindow
 64357 - window
 78460 - user32.GetParent
133067 - KERNEL32.lstrlenA
212150 - KERNEL32.GetSystemTime
212155 - KERNEL32.GetLocalTime
217190 - KERNEL32.lstrcmpiA
261926 - KERNEL32.SetFilePointer
261927 - KERNEL32.ReadFile
Comment 2 Vitaly Lipatov 2009-01-05 16:05:50 MSK
Основной претендент - SetFilePointer
Возможно, после тестирования исправление включить в bugfix к 1.0.9
Comment 3 Vitaly Lipatov 2009-03-05 16:14:50 MSK
Created attachment 1093 [details]
Таблица с рейтингом функций

Функции, на которые нужно обратить внимание (замедляют выполнение отчёта):
SetTextColor
IscharAlphaNumericA
HeapAlloc/HeapFree
GetDlgItem
GetTopWindow
SelectObject
GetWindow
GetTickCount
FillRect
ReadFile
SetFilePointer
GetSystemTime
GetLocalTime

Вообще в следующий раз надо вычислять рейтинг как
время выполнения * коэф. замедления * количество
Comment 4 Александр Морозов 2009-04-03 19:37:47 MSD
GetTickCount64 можно переделать так, чтобы она брала время из периодически обновляемой разделяемой области памяти. Судя по тестовой реализации, это должно обеспечить заметное уменьшение времени выполнения функции:

Test for            GetTickCount64 .....   0.319mks pc ( 1115 ms) ( 25%) (1/10 - 3.50m iterations)

Test for            GetTickCount64 .....   0.013mks pc (   45 ms) (  1%) (1/10 - 3.50m iterations)
Comment 5 Александр Морозов 2009-04-06 18:48:27 MSD
Реализовал получение функцией NtQuerySystemTime времени от wineserver через разделяемую память.

builder
До:
Test for              GetTickCount .....   0.311mks
Test for            GetTickCount64 .....   0.307mks
Test for              GetLocalTime .....   0.843mks
Test for             GetSystemTime .....   0.529mks
После:
Test for              GetTickCount .....   0.064mks
Test for            GetTickCount64 .....   0.069mks
Test for              GetLocalTime .....   0.686mks
Test for             GetSystemTime .....   0.349mks

atlant
До:
Test for              GetTickCount .....   0.684mks
Test for            GetTickCount64 .....   0.660mks
Test for              GetLocalTime .....   1.366mks
Test for             GetSystemTime .....   0.886mks
После:
Test for              GetTickCount .....   0.076mks
Test for            GetTickCount64 .....   0.073mks
Test for              GetLocalTime .....   0.983mks
Test for             GetSystemTime .....   0.417mks

Если использовать в GetTickCount64 указатель на разделяемое время вместо вызова NtQuerySystemTime:
builder
Test for              GetTickCount .....   0.050mks
Test for            GetTickCount64 .....   0.053mks
Test for              GetLocalTime .....   0.686mks
Test for             GetSystemTime .....   0.343mks
atlant
Test for              GetTickCount .....   0.057mks
Test for            GetTickCount64 .....   0.050mks
Test for              GetLocalTime .....   0.980mks
Test for             GetSystemTime .....   0.374mks

GetTickCount вызывает GetTickCount64, но при этом на builder почему-то иногда первый оказывается быстрее второго.
Comment 6 Александр Морозов 2009-04-06 21:04:46 MSD
Оптимизировал GetSystemTime.

atlant
Test for             GetSystemTime .....   0.134mks
Comment 7 Александр Морозов 2009-04-07 16:48:50 MSD
Сделал операции чтения/записи в разделяемую память атомарными. Оптимизировал GetLocalTime.

atlant
Test for              GetTickCount .....   0.107mks
Test for            GetTickCount64 .....   0.094mks
Test for              GetLocalTime .....   0.183mks
Test for             GetSystemTime .....   0.180mks
builder
Test for              GetTickCount .....   0.067mks
Test for            GetTickCount64 .....   0.067mks
Test for              GetLocalTime .....   0.071mks
Test for             GetSystemTime .....   0.066mks

GetLocalTime и GetSystemTime вызывают NtQuerySystemTime и выполняют некоторые преобразования, возвращая время в другом формате.

Уменьшение среднего времени выполнения достигнуто засчёт сохранения времени, возвращаемого NtQuerySystemTime, и представления времени в формате, в котором его должна вернуть функция. Если функции будут вызываться достаточно часто (так, что NtQuerySystemTime возвращает одно и то же, это приблизительно 10 мс), они будут просто возвращать сохранённый результат. Чем реже вызываются функции, тем меньше уменьшение времени выполнения из-за данной оптимизации.
Comment 8 Александр Морозов 2009-04-09 17:48:56 MSD
Оптимизировал IsChar*A(). Измерения на atlant:
Test for       IscharAlphaNumericA .....   0.098mks
Test for       IscharAlphaNumericW .....   0.019mks
Test for              IscharAlphaA .....   0.098mks
Test for              IscharAlphaW .....   0.020mks
После оптимизации:
Test for       IscharAlphaNumericA .....   0.034mks
Test for              IscharAlphaA .....   0.034mks
Comment 9 Александр Морозов 2009-04-27 18:24:11 MSD
Внёс небольшие изменения в код GetTickCount64, чтобы __wine_get_shared_time не вызывалась при последующих вызовах GetTickCount64 независимо от успешности первого вызова.
Comment 10 Александр Морозов 2010-10-21 13:44:19 MSD
Некоторая оптимизация произведена, решено сейчас закрыть.
Comment 11 Денис Баранов 2010-12-03 17:43:39 MSK
открываю для выставления статуса отложена
Comment 12 Денис Баранов 2010-12-03 17:44:35 MSK
Откладываю.
Comment 13 Денис Баранов 2011-09-06 18:37:07 MSK
Были проведены работы по оптимизации. Что на текущей сборке и в eterhack?

(В ответ на comment #0)
> Есть тестовая база /ftp/pvt/Windows/1C/1Cv77_configs/Cntuik_2007_.tar.bz2, так
> же есть на cellar в sharewine. Там при вызове номенклатуры идет постоянный
> перерасчет итогов. 
> На винде он выполняется секунд 5-9, а в wine секунд 30.
Comment 14 Andrey Vusik 2011-09-30 20:25:16 MSK
В eterhack скорость перерасчета такая же как и в Windows - 5 секунд.