<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
	<channel>
		<title>Форум QUIK [тема: Влияние колбэков на производительность]</title>
		<link>http://forum.quik.ru</link>
		<description>Новое в теме Влияние колбэков на производительность форума  на сайте Форум QUIK [forum.quik.ru]</description>
		<language>ru</language>
		<docs>http://backend.userland.com/rss2</docs>
		<pubDate>Thu, 23 Jul 2026 00:47:21 +0300</pubDate>
		<item>
			<title>Влияние колбэков на производительность</title>
			<description><![CDATA[<b><a href="http://forum.quik.ru/messages/forum17/message82926/topic9609/">Влияние колбэков на производительность</a></b> в форуме <a href="http://forum.quik.ru/forum17/">Обмен опытом</a>. <br />
			Некоторые считают, что наличие пустых колбэков в скрипте не оказывает какой-либо значительной нагрузки на CPU.<br />Имеется ввиду, когда скрипт работает с одним или нескольким инструментом, а в колбэке стоит фильтр, отсеивающий все остальные инструменты, вида:<br /><table class="forum-spoiler"><thead onclick="if (this.nextSibling.style.display=='none') { this.nextSibling.style.display=''; BX.addClass(this, 'forum-spoiler-head-open'); } else { this.nextSibling.style.display='none'; BX.removeClass(this, 'forum-spoiler-head-open'); } BX.onCustomEvent('BX.Forum.Spoiler:toggle', [{node: this}]); event.stopPropagation();"><tr><th><div>Скрытый текст</div></th></tr></thead><tbody class="forum-spoiler" style="display:none;"><tr><td>
====code====
<pre>function OnParam(class_code, sec_code)
&nbsp;&nbsp;if class_code ~= class or sec_code ~= sec then return end
&nbsp;&nbsp;-- ...
end
function OnQuote(class_code, sec_code)
&nbsp;&nbsp;if class_code ~= class or sec_code ~= sec then return end
&nbsp;&nbsp;-- ...
end
function OnAllTrade(alltrade)
&nbsp;&nbsp;if alltrade.class_code ~= class or alltrade.sec_code ~= sec then return end
&nbsp;&nbsp;-- ...
end</pre>
=============
</td></tr></tbody></table><br />Давайте проверим. Для оценки оверхэда я буду использовать таблицу обезличенных сделок.<br />Сначала измеряем время загрузки таблицы с запущенным скриптом без колбэков (скрипт №1):<table class="forum-spoiler"><thead onclick="if (this.nextSibling.style.display=='none') { this.nextSibling.style.display=''; BX.addClass(this, 'forum-spoiler-head-open'); } else { this.nextSibling.style.display='none'; BX.removeClass(this, 'forum-spoiler-head-open'); } BX.onCustomEvent('BX.Forum.Spoiler:toggle', [{node: this}]); event.stopPropagation();"><tr><th><div>Скрытый текст</div></th></tr></thead><tbody class="forum-spoiler" style="display:none;"><tr><td>
====code====
<pre>local run = true
function OnStop() run = nil end

function main()
&nbsp;&nbsp;local n = getNumberOf("all_trades")
&nbsp;&nbsp;local m = n
&nbsp;&nbsp;message("Num all trades: " .. n)
&nbsp;&nbsp;repeat
&nbsp;&nbsp;&nbsp;&nbsp;sleep(1)
&nbsp;&nbsp;&nbsp;&nbsp;m = n; n = getNumberOf("all_trades")
&nbsp;&nbsp;&nbsp;&nbsp;if run == nil then return end
&nbsp;&nbsp;until n &#60; m
&nbsp;&nbsp;local t = os.clock()
&nbsp;&nbsp;message("Num all trades: " .. m)
&nbsp;&nbsp;repeat
&nbsp;&nbsp;&nbsp;&nbsp;sleep(1)
&nbsp;&nbsp;&nbsp;&nbsp;n = getNumberOf("all_trades")
&nbsp;&nbsp;&nbsp;&nbsp;if run == nil then return end
&nbsp;&nbsp;until n &#62;= m&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- ожидание пока прокачаются все сделки
&nbsp;&nbsp;t = os.clock() - t
&nbsp;&nbsp;message(string.format("%.1f s; num: %u; avg: %.3f ms", t, n, t / n * 1000))
end</pre>
=============
</td></tr></tbody></table><br />Затем измеряем время загрузки таблицы с запущенным скриптом, с пустым колбэком OnAllTrade (скрипт №2):<table class="forum-spoiler"><thead onclick="if (this.nextSibling.style.display=='none') { this.nextSibling.style.display=''; BX.addClass(this, 'forum-spoiler-head-open'); } else { this.nextSibling.style.display='none'; BX.removeClass(this, 'forum-spoiler-head-open'); } BX.onCustomEvent('BX.Forum.Spoiler:toggle', [{node: this}]); event.stopPropagation();"><tr><th><div>Скрытый текст</div></th></tr></thead><tbody class="forum-spoiler" style="display:none;"><tr><td>
====code====
<pre>local run = true
function OnStop() run = nil end

function main()
&nbsp;&nbsp;local n = getNumberOf("all_trades")
&nbsp;&nbsp;local m = n
&nbsp;&nbsp;message("Num all trades: " .. n)
&nbsp;&nbsp;repeat
&nbsp;&nbsp;&nbsp;&nbsp;sleep(1)
&nbsp;&nbsp;&nbsp;&nbsp;m = n; n = getNumberOf("all_trades")
&nbsp;&nbsp;&nbsp;&nbsp;if run == nil then return end
&nbsp;&nbsp;until n &#60; m
&nbsp;&nbsp;local t = os.clock()
&nbsp;&nbsp;message("Num all trades: " .. m)
&nbsp;&nbsp;repeat
&nbsp;&nbsp;&nbsp;&nbsp;sleep(1)
&nbsp;&nbsp;&nbsp;&nbsp;n = getNumberOf("all_trades")
&nbsp;&nbsp;&nbsp;&nbsp;if run == nil then return end
&nbsp;&nbsp;until n &#62;= m&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- ожидание пока прокачаются все сделки
&nbsp;&nbsp;t = os.clock() - t
&nbsp;&nbsp;message(string.format("with OnAllTrade:&nbsp;&nbsp;%.1f s; num: %u; avg: %.3f ms", t, n, t / n * 1000))
end

function OnAllTrade(alltrade) end</pre>
=============
</td></tr></tbody></table><br />Как использовать:<ol><li>Настройка получения данных выполняется через пункт меню Система / Настройки / Основные настройки..., раздел «Программа» / «Получение данных» / «Обезличенные сделки»<br />В поле «Выбрать классы инструментов» выбрать <B>все без фильтров</B>! Это важно для корректных измерений, ниже объясню почему.<br />Если у вас уже выбраны все классы без фильтров этот шаг можно пропустить. Если нет, - то нажать кнопку «Перезаказать данные».<br /> &nbsp;<li>Подождать пока прокачаются все сделки и запустить первый скрипт.<br /> &nbsp;<li>Снова перезаказать обезличенные сделки и дождаться, когда скрипт выведет итоговый результат и остановится.<br /> &nbsp;<li>Повторить 3-й пункт со вторым скриптом.<br /></ol>У меня получились такие результаты в QUIK 13.0.2.20:<br /><br />Скрипт №1:<br />
====code====
<pre>38.9 s; num: 5497547; avg: 0.007 ms</pre>
=============
Скрипт №2:<br />
====code====
<pre>with OnAllTrade:&nbsp;&nbsp;79.8 s; num: 5513332; avg: 0.014 ms</pre>
=============
В диспетчере задач это выглядит так:<table class="forum-spoiler"><thead onclick="if (this.nextSibling.style.display=='none') { this.nextSibling.style.display=''; BX.addClass(this, 'forum-spoiler-head-open'); } else { this.nextSibling.style.display='none'; BX.removeClass(this, 'forum-spoiler-head-open'); } BX.onCustomEvent('BX.Forum.Spoiler:toggle', [{node: this}]); event.stopPropagation();"><tr><th><div>Скрытый текст</div></th></tr></thead><tbody class="forum-spoiler" style="display:none;"><tr><td>[FILE ID=13414]</td></tr></tbody></table><br />Видно, что в первом случае упор идёт на пропускную способность канала (100 Мбит/с), т.е. гипотетически сделки могли загрузиться быстрее при более широком канале. Если у вас канал шире 100 Мбит/с, напишите, какие у вас результаты.<br />Во втором случае - занята только половина ширины канала. Очевидно упёрлись в CPU, и скрипт не успевает обрабатывать колбэки с той скоростью, с которой поступают сделки.<br />Среднее время обработки одной сделки в первом случае составляет 7 мкс, а во втором - 14 мкс.<br />Если у вас разницы нет, что с колбэком, что без него, значит узким местом является не процессор, а например, пропускная способность сети (подключение по Wi-Fi) или сервера.<br />Так, если выбрать заказ не всех обезличенных сделок, а только некоторых классов или отдельных инструментов, то время прокачки сделок с первым скриптом без колбэка практически не изменится, зато со вторым скриптом уменьшится. Это говорит о том, что данные поступают медленнее, чем их обрабатывает терминал, что не годится для оценки оверхэда.<br /><br />Результаты при одновременном запуске 5 и 10 копий скрипта №1:<br />
====code====
<pre>39.3 s; num: 5566964; avg: 0.007 ms
39.3 s; num: 5566984; avg: 0.007 ms
39.3 s; num: 5566984; avg: 0.007 ms
39.3 s; num: 5566984; avg: 0.007 ms
39.3 s; num: 5566984; avg: 0.007 ms</pre>
=============

====code====
<pre>39.1 s; num: 5583868; avg: 0.007 ms
39.1 s; num: 5583867; avg: 0.007 ms
39.1 s; num: 5583868; avg: 0.007 ms
39.1 s; num: 5583868; avg: 0.007 ms
39.1 s; num: 5583868; avg: 0.007 ms
39.1 s; num: 5583868; avg: 0.007 ms
39.1 s; num: 5583868; avg: 0.007 ms
39.1 s; num: 5583868; avg: 0.007 ms
39.1 s; num: 5583868; avg: 0.007 ms
39.1 s; num: 5583868; avg: 0.007 ms</pre>
=============
<table class="forum-spoiler"><thead onclick="if (this.nextSibling.style.display=='none') { this.nextSibling.style.display=''; BX.addClass(this, 'forum-spoiler-head-open'); } else { this.nextSibling.style.display='none'; BX.removeClass(this, 'forum-spoiler-head-open'); } BX.onCustomEvent('BX.Forum.Spoiler:toggle', [{node: this}]); event.stopPropagation();"><tr><th><div>Скрытый текст</div></th></tr></thead><tbody class="forum-spoiler" style="display:none;"><tr><td>[FILE ID=13412]</td></tr></tbody></table><br />Среднее время на сделку не изменилось. Ограничением по-прежнему выступает пропускная способность канала.<br /><br />Результаты при одновременном запуске 2 и 3 копий скрипта №2 (с колбэком):<br />
====code====
<pre>with OnAllTrade:&nbsp;&nbsp;132.1 s; num: 5628639; avg: 0.023 ms
with OnAllTrade:&nbsp;&nbsp;132.1 s; num: 5628645; avg: 0.023 ms</pre>
=============
<table class="forum-spoiler"><thead onclick="if (this.nextSibling.style.display=='none') { this.nextSibling.style.display=''; BX.addClass(this, 'forum-spoiler-head-open'); } else { this.nextSibling.style.display='none'; BX.removeClass(this, 'forum-spoiler-head-open'); } BX.onCustomEvent('BX.Forum.Spoiler:toggle', [{node: this}]); event.stopPropagation();"><tr><th><div>Скрытый текст</div></th></tr></thead><tbody class="forum-spoiler" style="display:none;"><tr><td>[FILE ID=13413]</td></tr></tbody></table><br />
====code====
<pre>with OnAllTrade:&nbsp;&nbsp;180.1 s; num: 5680264; avg: 0.032 ms
with OnAllTrade:&nbsp;&nbsp;180.1 s; num: 5680264; avg: 0.032 ms
with OnAllTrade:&nbsp;&nbsp;180.1 s; num: 5680264; avg: 0.032 ms</pre>
=============
<table class="forum-spoiler"><thead onclick="if (this.nextSibling.style.display=='none') { this.nextSibling.style.display=''; BX.addClass(this, 'forum-spoiler-head-open'); } else { this.nextSibling.style.display='none'; BX.removeClass(this, 'forum-spoiler-head-open'); } BX.onCustomEvent('BX.Forum.Spoiler:toggle', [{node: this}]); event.stopPropagation();"><tr><th><div>Скрытый текст</div></th></tr></thead><tbody class="forum-spoiler" style="display:none;"><tr><td>[FILE ID=13415]</td></tr></tbody></table><br />Среднее время на сделку увеличивается примерно на ~9 мкс с добавлением каждого нового скрипта.<br /><br />Данный тест показывает, что само по себе наличие даже пустого колбэка в скрипте оказывает влияние.<br />А поскольку колбэки работают в основном потоке квика, то это сказывается также и на работе графического интерфейса и квика в целом. <br />
			<img src="https://forum.quik.ru/bitrix/components/bitrix/forum.interface/show_file.php?fid=13412&" width="499" height="321" /><br /><img src="https://forum.quik.ru/bitrix/components/bitrix/forum.interface/show_file.php?fid=13413&" width="496" height="320" /><br /><img src="https://forum.quik.ru/bitrix/components/bitrix/forum.interface/show_file.php?fid=13414&" width="500" height="317" /><br /><img src="https://forum.quik.ru/bitrix/components/bitrix/forum.interface/show_file.php?fid=13415&" width="496" height="324" /><br /><i>22.07.2026 15:40:10, Старатель.</i>]]></description>
			<link>http://forum.quik.ru/messages/forum17/message82926/topic9609/</link>
			<guid>http://forum.quik.ru/messages/forum17/message82926/topic9609/</guid>
			<pubDate>Wed, 22 Jul 2026 15:40:10 +0300</pubDate>
			<category>Обмен опытом</category>
		</item>
	</channel>
</rss>
