Добрый день. Кто-нибудь может подсказать, есть какие-то принципиальные отличия, которые бы делали предпочтительным использование SearchItems или цикл getNumberOf/getItem для выбора значений из таблиц Quik? Одно отличие точно есть, это отсутствие трансляции ошибок при использовании SearchItems. Может еще что-то, например, блокировка таблицы, из которой идет выборка, или блокировка коллбэков?
Пользователь
Сообщений: Регистрация: 27.01.2017
02.08.2020 09:57:22
Самая главная проблема - это расход памяти. При переборе каждый раз получатся строка таблицы, в которой может быть много полей. Если это делать на каждом цикле алгоритма, то память прямо улетает.
SearchItems возвращает массив индексов отфильтрованных строк. Что само по себе уже меньше по объему, ну и, зачастую, надо просто последний взять, например.
Пользователь
Сообщений: Регистрация: 24.05.2020
02.08.2020 10:09:14
Ну память, если не сохранять промежуточные результаты, сборщик почистит. При SearchItems тоже есть накладные расходы при вызове функции QLua из ядра Quik. Больше интересуют именно возможное блокировки данных/потоков.
Пользователь
Сообщений: Регистрация: 24.05.2020
02.08.2020 10:21:28
Немного поясню, к чему вопрос. Если SearchItems выполняется в основном контексте, то вызов с тяжелой функцией, скорее всего, заблокирует коллбэки, причем во всех скриптах. Если в контексте вызывающего потока, то одновременный вызов из main и коллбэка может привести к конфликтам.
Пользователь
Сообщений: Регистрация: 24.05.2020
05.08.2020 07:40:04
Нужна какая-то особая отметка в теме, чтобы поддержка дала свои пояснения?
Пользователь
Сообщений: Регистрация: 21.08.2015
05.08.2020 10:18:48
Цитата
Сергей написал: Если SearchItems выполняется в основном контексте, то вызов с тяжелой функцией, скорее всего, заблокирует коллбэки, причем во всех скриптах.
Тут у вас путаница. Каким образом она может выполняться в основном потоке квика? Только будучи вызванной в колбеке каком-то. Так вот сам по себе вызов колбека не даст основному потоку делать что-либо еще, в том числе вызывать другие колбеки, пока вы из колбека этого не вернетесь, независимо от выполняемых в нем действий. Следовательно, без разницы, SearchItems в нем или явный цикл.
По вопросу что лучше - лучше не строить алгоритм так, чтобы приходилось снова и снова что-то искать, это в любом случае повышает сложность (в смысле о большое). Явный цикл имеет линейную сложность. Если, например, пройти по ТВС, на каждом тике вызывая поиск в той же ТВС, получим сложность уже квадратичную. Всегда лучше алгоритм с меньшей сложностью, даже если в нем константы больше, т.к. он остается работоспособным при масштабировании, а полиномиалка начинает тормозить уже с малых размерностей и с какого-то момента вешается навеки. Насчет сложности SearchItems послушал бы из первоисточника.
написал: Если SearchItems выполняется в основном контексте, то вызов с тяжелой функцией, скорее всего, заблокирует коллбэки, причем во всех скриптах.
Тут у вас путаница. Каким образом она может выполняться в основном потоке квика? Только будучи вызванной в колбеке каком-то. Так вот сам по себе вызов колбека не даст основному потоку делать что-либо еще, в том числе вызывать другие колбеки, пока вы из колбека этого не вернетесь, независимо от выполняемых в нем действий. Следовательно, без разницы, SearchItems в нем или явный цикл.
По вопросу что лучше - лучше не строить алгоритм так, чтобы приходилось снова и снова что-то искать, это в любом случае повышает сложность (в смысле о большое). Явный цикл имеет линейную сложность. Если, например, пройти по ТВС, на каждом тике вызывая поиск в той же ТВС, получим сложность уже квадратичную. Всегда лучше алгоритм с меньшей сложностью, даже если в нем константы больше, т.к. он остается работоспособным при масштабировании, а полиномиалка начинает тормозить уже с малых размерностей и с какого-то момента вешается навеки. Насчет сложности SearchItems послушал бы из первоисточника.
В чем путаница? Понятно, что если я читаю таблицу из коллбэка, то без разницы, будет это простой перебор, или SearchItems. Но, где написано, что SearchItems не может выполняться в основном контексте квика, будучи запущенной из майна? Определенная логика в этом была бы - меньше затрат на синхронизацию обновления таблиц и чтения из них. По части сложности алгоритмов, согласен полностью, однако, реализация SearchItems мне не известна, вам, как я понимаю, тоже, вот и хотелось бы получить комментарии разработчиков. Ведь из каких-то соображений эту функцию добавили!
Пользователь
Сообщений: Регистрация: 17.12.2017
06.08.2020 09:54:22
Цитата
Сергей написал: Понятно, что если я читаю таблицу из коллбэка, то без разницы, будет это простой перебор, или SearchItem
Q
Пользователь
Сообщений: Регистрация: 21.08.2015
06.08.2020 12:01:53
Цитата
Сергей написал: Но, где написано, что SearchItems не может выполняться в основном контексте квика, будучи запущенной из майна?
Вопрос интересный. По идее, если искать надо в окне (а не в хранилище), вариантов, кроме как послать сообщение поиска этому окну, не просматривается. То есть фактически поиск будет выполняться в основном потоке. Предположил, что в этом случае колбек SearchItems будет выполняться в том потоке, в котором собственно идет поиск. Запустил поиск в all_trades - колбек вызывается в мейне. Ну ок, поиск в ТВС идет прямо в хранилище. Запустил поиск в money_limits - колбек вызывается в мейне. Не подтверждается предположение. Это таки еще ничего не значит, впрочем.
Пользователь
Сообщений: Регистрация: 21.08.2015
06.08.2020 16:07:08
Посмотрел еще на посылаемые главному потоку сообщения. В процессе вызова SearchItems в мейне никаких сообщений главному потоку не обнаружено. Гипотезу о выполнении поиска всегда в главном потоке отклоняем. Остается выяснить вопрос об асимтотической сложности функции.
Пользователь
Сообщений: Регистрация: 27.01.2017
06.08.2020 16:15:51
Мои наблюдения.
Хоть и говорят, что SearchItems быстрее, но я наблюдал такое поведение: Если таблица для выборки мала, то SearchItems будет предпочтительней. А вот если она большая, скажем таблица обезличенных сделок, то здесь уже не все так очевидно. SearchItems вызывало большую нагрузку, нежели прямой перебор. При этом выборка идет с запоминанием последнего прочитанного индекса, чтобы сузить последующие запросы. Т.е. размер исходной таблицы как-то влиял на результат, хотя, по идее, реализация должна быть тоже простым перебором с вызовом функции фильтрации для каждой строки.
Если просто написать некий цикл на 10 млн. повторений перебора, скажем таблицы из 10 строк, то особой разницы нет. Здесь я бы предпочел SearchItems, т.к. памяти меньше уйдет.
Пользователь
Сообщений: Регистрация: 21.08.2015
06.08.2020 16:57:32
Линейная у SearchItems сложность. Искал в ТВС. Оси условные.
Пользователь
Сообщений: Регистрация: 24.05.2020
06.08.2020 17:54:36
Цитата
Anton написал: Линейная у SearchItems сложность. Искал в ТВС. Оси условные.
Да, тоже посмотрел, линейная. Утверждение, что SearchItems работает быстрее, стало еще более загадочно, с чего бы?
написал: Линейная у SearchItems сложность. Искал в ТВС. Оси условные.
Да, тоже посмотрел, линейная. Утверждение, что SearchItems работает быстрее, стало еще более загадочно, с чего бы?
Цикл перебора по getitem гоняет ВСЕ данные через бутылочное горлышко между скриптом и терминалом. На этом много потерь.
SearchItems при наличии фильтрации прореживает данные хранилища внутри qlua и выдает на гора уже выборку. За счет этого идет значительная экономия при правильно выбранных фильтрах.
Пасхалочка для Алексея Иванникова:
Пользователь
Сообщений: Регистрация: 21.08.2015
06.08.2020 19:07:43
Цитата
написал: Цикл перебора по getitem гоняет ВСЕ данные через бутылочное горлышко между скриптом и терминалом. На этом много потерь.
Звучит логично. Но вот сделал поиск с колбеком, всегда возвращающим false. То есть он всегда пройдет по всему диапазону и не вернет в итоге ничего. И вариант с циклом, тоже тупо весь диапазон getItem. Два прохода, один - первый миллион записей ТВС, второй - второй миллион, дабы видеть, зависит ли от положения диапазона в таблице. Ожидал, что SearchItems даст график ниже цикла. А вижу вот такую вот картиночку
Пользователь
Сообщений: Регистрация: 21.08.2015
06.08.2020 19:20:27
Хотя да, если в строке параметров указать только одно поле (qty), получаем совсем другую картину Таким образом, на вопрос чем SearchItems быстрее, отвечаем - чем меньше полей требуется сравнивать, тем меньше константы.
Пользователь
Сообщений: Регистрация: 24.05.2020
07.08.2020 20:06:47
Цитата
Anton написал: Хотя да, если в строке параметров указать только одно поле (qty), получаем совсем другую картину
Таким образом, на вопрос чем SearchItems быстрее, отвечаем - чем меньше полей требуется сравнивать, тем меньше константы.
Тоже была такая мысль, что выигрыш будет в случае указания ограниченного списка полей. Спасибо за интересный разбор:)
Пользователь
Сообщений: Регистрация: 17.12.2017
07.08.2020 20:46:07
Цитата
Anton написал: Таким образом, на вопрос чем SearchItems быстрее, отвечаем - чем меньше полей требуется сравнивать, тем меньше константы.
Разработчиков Sergey Gorokhov, прошу добавить эту информацию в мануал qlua.chm