Ускоряем скрипт и выкидываем sleep

Страницы: 1
RSS
Ускоряем скрипт и выкидываем sleep
 
Добрый день, Всем
С момента появления VMLua в КВИКЕ неоднократно рассказывал о том, что применение event вместо sleep
не только экономит ресурсы процессора, но и позволяет не пропускать события в колбеках и максимально бысто на них реагировать.
говорил об этом например здесь:
https://forum.quik.ru/forum17/topic8426/
---------------------
К сожалению, кроме бессмысленного хамства некоторых посетителей форума, ничего конкретного никто не написал.
---------------
Но вот наконец-то появился вменяемый чел paluke .
и после моей попытки в очередной раз объяснить преимущество event
https://forum.quik.ru/messages/forum10/message75435/topic8600/#message75435






он все же решил проверить это и убедился, что это так действительно:  

Код
Просто проверка концепции:
Кодw32 = require("w32")

run = true
evt = false

function OnInit()
  evt = w32.CreateEvent(nil, 0, 0, nil)
end

function OnStop()
 run = false
 w32.SetEvent(evt)
end

function main()
  while run do
     w32.WaitForSingleObject(evt, 1000000)
  end
  w32.CloseHandle(evt)
end

В колбеках вызываете SetEvent - main сразу просыпается.
С чем Всех и поздравляю.
 
Присоединяюсь.
Не нужно иметь много образования чтобы понять что техника с ожиданием событий эффективна.
А реализация не так сложна, как кажется на первый взгляд.
 
Эту возможность надо в квик добавить.
 
Для моих целей сообщения тоже оказались заметно быстрее, чем sleep. На скрине для каждой пары неродных для квика стаканов левый отрисован с ожиданием через сообщения, правый - через sleep. Внизу стаканов статистика потерь, они на правых стаканах больше. Kernel time и cpu time тоже меньше на потоке, который ждёт событий.
Поскольку рисование стаканов идёт в main скрипта, нельзя использовать WaitForMultipleObjects для событий из OnQuote и OnStop, нужно MsgWaitForMultipleObjectsEx, чтобы main включался на событиях GUI для стаканов. Её нет в w32, пришлось подключать через cffi-lua. Инструкция по сборке написана тут. Если сравнивать время исполнения между w32 и cffi-lua, то конечно же w32 быстрее (SetEvent на 12%, CreateEvent на 23%).
Важные части кода:

Код
local w32 = require "w32-ext"
local ffi = require "cffi"
local SetEvent = w32.SetEvent
local MsgWaitForMultipleObjectsEx = w32.MsgWaitForMultipleObjectsEx
local cb_t = {'EDM4','SiM4','CRM4','CNYRUB_TOM'}
local e_quote, e_stop
local is_run = true

function OnQuote(class_code, sec_code)
  local sent = cb_t[sec_code]
  if sent then
    cb_t[sec_code] = sent + 1
    SetEvent(e_quote)
  end
end
function OnStop()
    is_run = false
    SetEvent(e_stop)
end
function main()
  e_stop = w32.CreateEvent(nil, 0, 0, nil)
  e_quote = w32.CreateEvent(nil, 0, 0, nil)
  local events = ffi.new("HANDLE[2]", {e_quote, e_stop})
  local WAIT_TIMEOUT = w32.WAIT_TIMEOUT
  while is_run do
    local res = MsgWaitForMultipleObjectsEx(2, events, 500, 7423, 0) -- QS_ALLINPUT == 7423
    if res == 1 then break end
      if res == WAIT_TIMEOUT then
         -- по таймауту обработать сообщения, например, о смене foreground окна
      else
         -- обновить стаканы
      end
    end
  end
end

w32-ext.lua:
Код
local w32 = require("w32")
local ffi = require "cffi"
ffi.cdef [[
    typedef unsigned int UINT;
    typedef unsigned long DWORD;
    typedef long long LRESULT;
    typedef long long LPARAM;
    typedef unsigned long long WPARAM;
    //typedef void* HWND; // in windows
    typedef intptr_t HWND; // uintptr_t not ok as it appends 'ULL', LPARAM also ok
    typedef intptr_t HANDLE;

    void SetLastError(DWORD);
    //LRESULT SendMessageA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
    HWND GetForegroundWindow();
    DWORD MsgWaitForMultipleObjectsEx(DWORD nCount, const HANDLE *pHandles, DWORD dwMilliseconds, DWORD dwWakeMask, DWORD dwFlags);
]]

w32.SetLastError = ffi.C.SetLastError
w32.GetForegroundWindow = ffi.C.GetForegroundWindow
w32.MsgWaitForMultipleObjectsEx = ffi.C.MsgWaitForMultipleObjectsEx
-- those calls trigger 127 error on first invocation
w32.SetLastError(0)

return w32
Страницы: 1
Читают тему
Наверх