Страницы: 1 2 След.
RSS
Самый быстрый способ подтягивать значения по ключу
 
Доброго вечера, Планетяне!
В прошлой своей теме более-менее разобрался с созданием UDF'ок начального уровня. Теперь же вопрос глобальный и серьёзный.
Увидел тут статью на тему мегаускорения ВПР'а (или связки ИНДЕКС+ПОИСКПОЗ) за счёт "неточного" поиска. Есть, правда, нюанс — столбец поиска должен быть отсортирован по возрастанию. На Планете нашёл тему, в которой этот вопрос решён.
Однако, это для отсортированного массива и лучший ли это вариант для Excel? Можно ли ещё как-то ускорить и как сортировать массив в коде?
Прошу писать свои наработки и просто советы на тему. Файл-пример прилагается (большой, поскольку 2 столбца по 500к строк). Маленький пример тут в посте. Данные в примерах - рандомная генерация
Изменено: Jack Famous - 05.10.2017 12:15:13
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
не очень понял, что же вас интересует, в чем вопрос-то?
F1 творит чудеса
 
По названию темы: в ВПР неприменим бинарный поиск при несортированных данных. Все? Тема закрыта?
Или вопрос о сортировку в массиве?

Цитата
Файл-пример... большой
Т.е. для примера совсем никак нельзя 100 строк, а проверять потом на своем в 500К?
Через время ссылки стают недоступны, темы остаются без файлов. Неужели этого не знали?
 
Максим Зеленский, если данные неотсортированы, то будет ли прирост скорости при сортировке массива внутри UDF и дальнейшем использовании бинарного поиска через ВПР или ИНДЕКС+ПОИСКПОЗ.

vikttur, по этому названию желающие без проблем найдут тему. А если в название подтягивать всю "простыню" с предысторией и вариантами, то никто и никогда тему не найдёт, а если и найдёт, то не откроет, испугавшись названия - я так думаю. Смысл темы в написании наибыстрейшей UDF по поиску и подтягиванию соответствий. Так как бинарный поиск (дающий огромный прирост в скорости) осуществим только с отсортированными данными, смысл темы сводится к поиску оптимального из способов приведения исходных данных к отсортированному виду (типа макроса по сортировке таблицы или же сортировке массива внутри UDF).
Про файл-пример: я не разобрался, как тестить внутри кода. Такой объём сделал для теста "в лоб" с секундомером в руке))) средневековье, однако, но что делать… Добавлю маленький пример.

Не хотел давать название о сортировке, потому что интересны опыт и мысли людей в целом. Может кто-то предложит вообще другой вариант…

Возможное новое название темы: «Бинарный поиск в Excel. Как искать быстро.»
Изменено: Jack Famous - 05.10.2017 12:25:43
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
Можно ли ещё как-то ускорить и как сортировать массив в коде?
да, написать свою библу(где используются linq и бинарный поиск(первое, что пришло в голову)), передавать ей параметры и получать результат. И это для реально больших массивов. А так, все эти ускоренные поиски в excel от лукавого. В темы я не вдавался, но мне хватает find :)
 
Цитата
Jungl написал:
написать свою библу
не видели ничего такого готового?
Цитата
Jungl написал:
мне хватает find
а какой из этих кодов с Find будет быстрее, как вы считаете?
Изменено: Jack Famous - 05.10.2017 12:24:44
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Разберитесь, что нужно.
Если бинарный поиск, то НЕ СОРТИРОВКА. Если нужна сортировка, то при чем здесь бинарный поиск?
 
vikttur, нужен самый быстрый способ подтягивать значения по ключу :)  интернет говорит, что этот способ - бинарный поиск. А вот уже для того, чтобы этот бинарный поиск мог работать, данные должны быть отсортированы по возрастанию
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Эта тема сродни мануалу как почесать левое ухо правой рукой через голову ...
что значит самый быстрый? Это очень относительное понятие ...
Если в массиве ключ будет первым, то прямой перебор будет быстрее бинарного поиска ... и наоборот.
Вообще функция ВПР и так не медленная, зачем еще ее насиловать?
Цитата
Jack Famous написал:
А вот уже для того, чтобы этот бинарный поиск мог работать, данные должны быть отсортированы по возрастанию
следовательно название темы ни о чем. Вас интересует сортировка массива, так и нужно называть тему...
Но такие вопросы уже были и Слэн реализовал очень шустрый алгоритм сортировки больших массивов.
Изменено: Ivan.kh - 05.10.2017 13:06:10
 
Цитата
Ivan.kh написал:
 Слэн  реализовал очень шустрый алгоритм сортировки больших массивов
не помните, как тема называлась? Или как давно была…
Цитата
Ivan.kh написал:
что значит самый быстрый? Это очень относительное понятие ...
имеются ввиду большие объёмы данных в excel. На больших объёмах при прочих равных прямой перебор же проиграет - разве нет?
Изменено: Jack Famous - 05.10.2017 13:18:37
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
а какой из этих кодов с Find будет быстрее, как вы считаете?
Jack Famous, это уже некрасиво. "Свистни Ваня, ты глупее"?. Берите и проверяйте на своих файлах, это же Вам надо(во всяком случае Вы считаете, что надо). А то чуть ли не во всех темах советы гостям раздаете, три года на форуме, но такой пустяк самостоятельно осилить не можете.
Я сам - дурнее всякого примера! ...
 
Цитата
kuklp написал:
советы гостям раздаете, три года на форуме, но такой пустяк самостоятельно осилить не можете
ну, знаете, для кого пустяк, а для кого нет. Вот, будь для меня пустяк - я бы подсказал, помог (что и пытаюсь делать "чуть ли не во всех темах" и, иногда не в тему). А, извините, 3 года на форуме - это не 3 года обучения VBA. Почему некрасиво не понимаю. Если человек знает, например, что Offset быстрее индекса, почему бы не ответить. А, если не знает/не сталкивался, то на нет и суда нет…
И вообще "за спрос не дают в нос", а вы вот даёте — вот что несправедливо. Профессионал высочайшего уровня, между прочим.
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Причем тут это знает\незнает? На форуме полно примеров измерения времени выполнения макросов. Кто Вам не дает замерить и сравнить? Но Вы грузите других. Это и некрасиво.
Я сам - дурнее всякого примера! ...
 
kuklp, есть у меня эти примеры - ну не разобрался я в них, пока что… Я же не требую (боже упаси - ни в коем случае) ответа. Знаете, что я часто вижу на форуме? Кто-то спрашивает, как ускорить макрос и опытный VBA'шник говорит: «да нафига ты вообще используешь вот это и вот это - это "тяжёлые" штуки и от них никакой пользы. Используй лучше вот это» вот об этом я и говорю - о быстром совете, основанном на многолетнем опыте.
Я же, хоть и давно на форуме, но недалеко от новичков ушёл, т.к. работаю на стройке и VBA это просто способ повысить качество работы. Не судите строго, пожалуйста…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Я вообще сварщик и ни к ВБА, ни к Эксу, ни вообще к компу никакого отношения не имею ни по работе ни вне ее. :D
Я сам - дурнее всякого примера! ...
 
kuklp, тогда вы самый прошаренный сварщик из мне известных)))
что ж — буду разбираться и ждать ответов, вдруг кому интересно. А не получится, тогда буду думать о связке через PQ, Access, SQL (в нём уже и так всё оптимизировано по поиску) и иже с ними

Кажется, я нашёл (правда в архиве) сортировку Слэма  :)
Изменено: Jack Famous - 05.10.2017 14:21:10
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Раз уж тема уходит в сторону сортировки, то поделюсь самыми интересными кодами, на мой взгляд:
Слэн
nerv
excelvba
Что касается "подтягивания по ключу", придумал несколько костылей/решений:
1. Использовать макрос вместо макрофункции, который сортирует словарь на листе по возрастанию и, затем, (после парочки проверок) использует ИНДЕКС+ПОИСКПОЗ (с 4ым параметром=1) для проставления значений.
2. Вообще избавиться от необходимости поиска по словарю за счёт связывания таблиц между собой по ключам через PQ (или другие решения)

Вообще, в процессе поиска ответов на мои вопросы, среди всевозможных супероптимальных сортировок массивов и уникальных алгоритмов уловил (так это или нет - не знаю) одну мысль (справедливую для одномерных диапазонов) : сортировка простым макросом на листе бьёт всё
Изменено: Jack Famous - 05.10.2017 15:41:23
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
kuklp,Вот это сварщик))))) Капец у меня две вышки но так как Вы в VBA не фига не шарю))))
 
Еще одна архивная тема про сортировку массивов, с подборкой ссылок от Владимира (ZVI)
Согласие есть продукт при полном непротивлении сторон
 
Sanja, спасибо за ссылку. Я из этого поста код nerv'а взял (выложен в моём предыдущем посту) — я так понял, что именно у него лучшее время получилось
Изменено: Jack Famous - 05.10.2017 18:40:10
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
я так понял, что именно у него лучшее время получилось
Пузырьковая сортировка, пусть даже и "умная", все равно очень медленная, и для 500к данных не подойдет
 
MCH, спасибо за пояснение) а как бы вы сделали, если ограничиться Excel'ем и VBA?  может методика, там, какая))) доп столбцы, в конце-концов  :)
Изменено: Jack Famous - 05.10.2017 20:04:53
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Все зависит от задачи, может нужно смотреть в сторону SQL?

Если есть большой объем данных и нужно только один раз найти значение, то используем обычный перебор. Асимптотика алгоритма O(n)
Если нужен многократный поиск, то имеет смысл один раз отсортировать массив, а затем бинарным поиском искать значения.
При этом сама сортировка это достаточно затратный способ, чтобы каждый раз перед поиском значений сортировать массив, имеет смысл это сделать только один раз.
Асимптотика у "пузырьковой сортировки" O(n^2), у "быстрой сортировки" - O(n * LOG n) (в худшем случае может быть O(n^2)), при этом поиск элементов осуществляется достаточно быстро за O(LOG n)

Встроенный механизм сортировку в самом Excel достаточно быстрый, думаю что любая реализация сортировки средствами VBA будет медленнее.
Изменено: MCH - 06.10.2017 08:03:57
 
Доброе время суток.
Цитата
MCH написал:
пусть даже и "умная"
Михаил, не всё так просто. Есть версия пузырьковой сортировки, называемая "гребешковая", которая вполне себе быстрая Пузырьковая сортировка и все-все-все, хотя расходится с этим исследованием. Свою версию на VBA сравнивал с quick sort на нём же. до 300000 случайных равномерно сгенерированных значений -  почти нет разницы.
Jack Famous, вы всё же не столь обще описали бы задачу. Так сложно что-то предложить, поскольку рассуждения скатываются к сферическому коню в вакууме :)  Если массив данных большой, то, на мой всгляд, проще хранить в таблице базы Access, создав индекс по полю соединения, и оттуда дёргать требуемые значения запросом. Но опять же, нужно понимать цикл работы для выборки.
 
Доброго утра!
MCH и Андрей VG, спасибо вам большое за подробности и сравнения! Вот это я и называю живым обсуждением и "делиться опытом"  :)
Цитата
Андрей VG написал:
не столь обще описали бы задачу
сделал это, повторюсь, чтобы различные варианты послушать, как, например, у вас или MCH.
Согласен - довольно размытая постановка вопроса.
Расскажу всю историю (осторожно - простыня):
Вопрос: ВПР с ИСТИНОЙ в 4ом параметре и ПОИСКПОЗ с ИСТИНОЙ в 3ем параметре при обеспечении отсортированных данных дадут одинаковый прирост?
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Я бы от другого в данном случае плясал:
- есть 500к строк, нужно найти 1 значение (рассчитать формулу ВПР) - здесь без разницы вообще. Никакие макросы не ускорят обычную функцию. Впрочем, MCH об этом и писал.
- есть 500к строк, нужно найти 500к значений в справочнике (т.е. ВПР для каждой строки)  - вот здесь уже надо по конкретным кейсам:

1) можно ли предварительно отсортировать справочник на листе?
2) если нет - то надо оценить варианты работы макроса:
   а) копируем лист справочника, штатно сортируем, ВПР-им, если нужно - убиваем копию
   б) копируем справочник в массив, сортируем массив в памяти, впр-им массив
   в) копируем справочник в массив, запихиваем его в словарь, достаем из словаря по ключам.
   г) то же самое с коллекциями
   д) ничего никуда не копируем, а ВПРим макросом без бинарного поиска маленькими порциями :)

Вот что-то мне говорит, что варианты в) или г) будут быстрее, чем вариант б) - если я правильно понимаю, запихивание в словарь это O(n), в то время как сортировка всяко больше
Цитата
MCH написал:
у "пузырьковой сортировки" O(n^2), у "быстрой сортировки" - O(n * LOG n)
, при сравнимом (наверное, не проверял) времени поиска в словаре и бинарного ВПР.

а вариант а) - тоже любопытно, можно проверить, не быстрее ли на объеме.
F1 творит чудеса
 
Ух круто, Максим!))) Спасибо вам за варианты и советы!
Со словарями своя тема: так как это файл-конструктор, то словари, как и сама база, заполняются постепенно пользователем — соответственно, либо пополнять VBAшный словарь новыми данными и удалять из него, если что-то изменилось, либо убивать старый словарь и каждый раз грузить новый. Так как (воп.1) сортировка на листе вполне допустима, то так я, скорее всего, и поступлю, тем паче, что со словарями, массивами и иже с ними мне только ближе к концу года предстоит столкнуться.
Буду оптимизировать, пока хватит навыков)))) уже смотрю в сторону Access, SQL и PQ с PP))) последние 2 в любом случае нужны - для аналитики. А пока я PQ использую для связи один-ко-многим (спасибо Андрею) и по-мелочи для причёсывания данных или отображения кросс-таблиц в виде плоских (и наоборот)
Максим, кстати, Андрей 2 ссылки дал на обзор методов сортировки и на тест производительности. Обзор мне очень зашёл - там гифки так наглядно принцип работы показывают, что аж загляденье  :D
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Максим Зеленский написал:
Вот что-то мне говорит, что варианты в) или г) будут быстрее, чем вариант б) - если я правильно понимаю, запихивание в словарь это O(n), в то время как сортировка всяко больше
Максим, вы забыли учесть, что стоимость вставки в словарь/коллекцию log(n) , если все элементы массива уникальны, так что тоже n * log(n)
 
Внесу свои 5 копеек. Если есть возможность отсортировать справочную таблицу и объемы достаточно велики (100 т. строк и более), то имеет смысл формулу
Код
=ВПР(D1;A:B;2;0)
заменить на
Код
=ЕСЛИ(ВПР(D1;A:B;1;1)=D1;ВПР(D1;A:B;2;1);НД())
эффект - более чем заметен :)  
 
webley, рад вас видеть в своей теме! Если не ошибаюсь, то, что вы предлагаете, и есть бинарный поиск с проверкой, описанный тут. ikki (RIP) в сообщении #20 также предлагал ускорить функцию, проверяя через ИНДЕКС, а не ВПР'ом.
Изменено: Jack Famous - 06.10.2017 17:35:23
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Страницы: 1 2 След.
Наверх