Добрый день. Кто-нибудь может подсказать, есть какие-то принципиальные отличия, которые бы делали предпочтительным использование SearchItems или цикл getNumberOf/getItem для выбора значений из таблиц Quik? Одно отличие точно есть, это отсутствие трансляции ошибок при использовании SearchItems. Может еще что-то, например, блокировка таблицы, из которой идет выборка, или блокировка коллбэков?
Самая главная проблема - это расход памяти. При переборе каждый раз получатся строка таблицы, в которой может быть много полей. Если это делать на каждом цикле алгоритма, то память прямо улетает.
SearchItems возвращает массив индексов отфильтрованных строк. Что само по себе уже меньше по объему, ну и, зачастую, надо просто последний взять, например.
Ну память, если не сохранять промежуточные результаты, сборщик почистит. При SearchItems тоже есть накладные расходы при вызове функции QLua из ядра Quik. Больше интересуют именно возможное блокировки данных/потоков.
Немного поясню, к чему вопрос. Если SearchItems выполняется в основном контексте, то вызов с тяжелой функцией, скорее всего, заблокирует коллбэки, причем во всех скриптах. Если в контексте вызывающего потока, то одновременный вызов из main и коллбэка может привести к конфликтам.
Сергей написал: Если SearchItems выполняется в основном контексте, то вызов с тяжелой функцией, скорее всего, заблокирует коллбэки, причем во всех скриптах.
Тут у вас путаница. Каким образом она может выполняться в основном потоке квика? Только будучи вызванной в колбеке каком-то. Так вот сам по себе вызов колбека не даст основному потоку делать что-либо еще, в том числе вызывать другие колбеки, пока вы из колбека этого не вернетесь, независимо от выполняемых в нем действий. Следовательно, без разницы, SearchItems в нем или явный цикл.
По вопросу что лучше - лучше не строить алгоритм так, чтобы приходилось снова и снова что-то искать, это в любом случае повышает сложность (в смысле о большое). Явный цикл имеет линейную сложность. Если, например, пройти по ТВС, на каждом тике вызывая поиск в той же ТВС, получим сложность уже квадратичную. Всегда лучше алгоритм с меньшей сложностью, даже если в нем константы больше, т.к. он остается работоспособным при масштабировании, а полиномиалка начинает тормозить уже с малых размерностей и с какого-то момента вешается навеки. Насчет сложности SearchItems послушал бы из первоисточника.
Сергей написал: Если SearchItems выполняется в основном контексте, то вызов с тяжелой функцией, скорее всего, заблокирует коллбэки, причем во всех скриптах.
Тут у вас путаница. Каким образом она может выполняться в основном потоке квика? Только будучи вызванной в колбеке каком-то. Так вот сам по себе вызов колбека не даст основному потоку делать что-либо еще, в том числе вызывать другие колбеки, пока вы из колбека этого не вернетесь, независимо от выполняемых в нем действий. Следовательно, без разницы, SearchItems в нем или явный цикл.
По вопросу что лучше - лучше не строить алгоритм так, чтобы приходилось снова и снова что-то искать, это в любом случае повышает сложность (в смысле о большое). Явный цикл имеет линейную сложность. Если, например, пройти по ТВС, на каждом тике вызывая поиск в той же ТВС, получим сложность уже квадратичную. Всегда лучше алгоритм с меньшей сложностью, даже если в нем константы больше, т.к. он остается работоспособным при масштабировании, а полиномиалка начинает тормозить уже с малых размерностей и с какого-то момента вешается навеки. Насчет сложности SearchItems послушал бы из первоисточника.
В чем путаница? Понятно, что если я читаю таблицу из коллбэка, то без разницы, будет это простой перебор, или SearchItems. Но, где написано, что SearchItems не может выполняться в основном контексте квика, будучи запущенной из майна? Определенная логика в этом была бы - меньше затрат на синхронизацию обновления таблиц и чтения из них. По части сложности алгоритмов, согласен полностью, однако, реализация SearchItems мне не известна, вам, как я понимаю, тоже, вот и хотелось бы получить комментарии разработчиков. Ведь из каких-то соображений эту функцию добавили!
Сергей написал: Но, где написано, что SearchItems не может выполняться в основном контексте квика, будучи запущенной из майна?
Вопрос интересный. По идее, если искать надо в окне (а не в хранилище), вариантов, кроме как послать сообщение поиска этому окну, не просматривается. То есть фактически поиск будет выполняться в основном потоке. Предположил, что в этом случае колбек SearchItems будет выполняться в том потоке, в котором собственно идет поиск. Запустил поиск в all_trades - колбек вызывается в мейне. Ну ок, поиск в ТВС идет прямо в хранилище. Запустил поиск в money_limits - колбек вызывается в мейне. Не подтверждается предположение. Это таки еще ничего не значит, впрочем.
Посмотрел еще на посылаемые главному потоку сообщения. В процессе вызова SearchItems в мейне никаких сообщений главному потоку не обнаружено. Гипотезу о выполнении поиска всегда в главном потоке отклоняем. Остается выяснить вопрос об асимтотической сложности функции.
Хоть и говорят, что SearchItems быстрее, но я наблюдал такое поведение: Если таблица для выборки мала, то SearchItems будет предпочтительней. А вот если она большая, скажем таблица обезличенных сделок, то здесь уже не все так очевидно. SearchItems вызывало большую нагрузку, нежели прямой перебор. При этом выборка идет с запоминанием последнего прочитанного индекса, чтобы сузить последующие запросы. Т.е. размер исходной таблицы как-то влиял на результат, хотя, по идее, реализация должна быть тоже простым перебором с вызовом функции фильтрации для каждой строки.
Если просто написать некий цикл на 10 млн. повторений перебора, скажем таблицы из 10 строк, то особой разницы нет. Здесь я бы предпочел SearchItems, т.к. памяти меньше уйдет.
Anton написал: Линейная у SearchItems сложность. Искал в ТВС. Оси условные.
Да, тоже посмотрел, линейная. Утверждение, что SearchItems работает быстрее, стало еще более загадочно, с чего бы?
Цикл перебора по getitem гоняет ВСЕ данные через бутылочное горлышко между скриптом и терминалом. На этом много потерь.
SearchItems при наличии фильтрации прореживает данные хранилища внутри qlua и выдает на гора уже выборку. За счет этого идет значительная экономия при правильно выбранных фильтрах.
s_mike@rambler.ru написал: Цикл перебора по getitem гоняет ВСЕ данные через бутылочное горлышко между скриптом и терминалом. На этом много потерь.
Звучит логично. Но вот сделал поиск с колбеком, всегда возвращающим false. То есть он всегда пройдет по всему диапазону и не вернет в итоге ничего. И вариант с циклом, тоже тупо весь диапазон getItem. Два прохода, один - первый миллион записей ТВС, второй - второй миллион, дабы видеть, зависит ли от положения диапазона в таблице. Ожидал, что SearchItems даст график ниже цикла. А вижу вот такую вот картиночку