Страницы: 1
RSS
Получение списка уникальных значений из одномерного массива VBA
 
Собственно это очередной тест драйв по скорости...
-------------
Сравнивались (отбор уникальных среди целых чисел):
- собственная процедура
- ArrayList (самый тормозной)
- Dictionary
- Collection
- Hashtable (System.Collections.Hashtable)
сравнение не совсем корректное, т.е. процедура выдает сразу массив с уникальными значениями, а все объекты только наполнялись.
---------------
Результат теста (числа):
Скрытый текст

Строки (среди финалистов :) ):
Скрытый текст

Тестовый макрос:
Скрытый текст

Добытчик уников на массивах:
Скрытый текст
Изменено: Anchoret - 05.03.2019 12:23:30
 
Anchoret, большое спасибо! Заинтересован))) и сортер годный. Пара вопросов:
1. передаём в UniList 2 массива ("принудительный" Variant() и вариативный Variant) - почему так? Мы же просто должны одномерный массив передать и получить на выходе уникальный (изменённый входящий) - не?
2. почему у сортера также аж 3 аргумента, причём последние 2 - границы массива (первого аргумента). Неужели он сам их определить не может?…
Изменено: Jack Famous - 04.03.2019 11:30:45
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous, кто-то так и не освоился с массивами + параметрами процедур?)
Квик не самой быстрой реализации. Но вроде работает корректно. Где-то здесь на форуме его встретил. Немного ускорил за счет Do While..Loop вместо While ...Wend
Изменено: Anchoret - 04.03.2019 12:32:07
 
Цитата
Anchoret: кто-то так и не освоился с массивами + параметрами процедур?
может быть… Разъясните?
Цитата
Anchoret: Квик не самой быстрой реализации
я использую вот этот
Скрытый текст
Изменено: Jack Famous - 04.03.2019 12:49:24
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
Мы же просто должны одномерный массив передать и получить на выходе уникальный (изменённый входящий) - не?
Можно и так, но входной массив с данными может быть полезен для других де. И поскольку он передается по ссылке, то поганить его содержимое не решился.
Цитата
Jack Famous написал:
почему у сортера также аж 3 аргумента, причём последние 2 - границы массива (первого аргумента)
QuickSort - рекурсивная процедура вызывающая сама себя.
 
Цитата
Anchoret: поскольку он передается по ссылке
если только поэтому, то почему не объявить byVal?
Цитата
Anchoret: QuickSort - рекурсивная процедура
ясненько - спасибо)
Изменено: Jack Famous - 04.03.2019 12:51:55
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
то почему не объявить byVal?
По ссылке быстрее и менее затратно по памяти на больших объемах.
 
Anchoret, и снова  я  :D приветствую!
Более корректное использование словаря и он снова в деле
КОДЫ
Изменено: Jack Famous - 16.04.2019 18:51:09
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Anchoret, доброго времени суток!  :)

1. Пытался адаптировать ваш текстовый сортер, чтобы сравнить с рекурсивным квиком (пустые и прочерки забивал строками, а не числами, как тут) — не получилось (не дождался и вырубил)
2. Нашёл сортировку Хоара со слиянием и вариант от mikerickson — не получилось (не дождался и вырубил)
3. Добавил в вашу сортировку вариант с текстовым сравнением (без учёта регистра). При таком сравнении время на этих данных увеличилось почти в 2 раза (8,1 против 4,2 сек). Разделение функции на 2 разные (чтобы вызывать соответствующую и при рекурсии лишний раз не проверять), выигрыша во времени не дало, поэтому оставил в одной функции. Пытался реализовать через StrComp, но он оказался дольше + в смешанных данных сортирует числа как текст (что неудивительно, ведь это функция сравнения СТРОК).
Интересно, что UCase быстрее UCase$ (во всяком случае, на этих данных), хотя я активно использую Left$, Mid$ и Right$, и они при сравнении были быстрее, чем "без долларов"
4. Устав пытаться усовершенствовать ваш вариант квика, принялся за сам поиск уникальных.
Не понял, зачем в вашем варианте несколько циклов, если всё просто - идём со второго и, если он не равен предыдущему, добавляем в массив уникальных…
Пробовал цикл For Each, но он подвёл, т.к. нужно идти со второго и дополнительные проверки сожрали время.
Если в мой поисковик уникальных передавать массив для наполнения (как у вас) то он немного быстрее (80 против 100 мс). Я считаю это лишним, поэтому преобразовываю входящий и проигрываю (150 против 100 мс). Разумеется, оба эти значения невероятно малы, а поэтому ваще пофиг)))
5. Сортировка на моих данных занимает 4 или 8 сек (если без учёта регистра). Предполагаю, что увеличить можно, через StrConv(,vbFromUnicode) + проверяя первые несколько символов для предварительного ветвления (как у вас в текстовом). Попробую что-то сообразить в этом плане. Если сможете что-то "допилить", то буду очень рад, т.к. текстовый получился очень шустрым (хоть и с ограничениями).
6. Получение уникальных словарём занимает всего 1 сек (на 1 млн!!!), что в 4 раза быстрее, т.к. не требует сортировки + данные остаются в исходном порядке (хорошо это или плохо).

Для себя решил следующее - при работе с большими данными, буду сортировать и загружать их в Public-массивы (хватило бы памяти  :D  ) при открытии файла. Далее, при работе с файлом, получить любую информацию из таких массивов можно будет мгновенно. Для стандартного же поиска уникальных в повседневных задачах словарь отлично подходит.

P.S.: указание массива в аргументе функции для сортировки через arr() вместо вариативного arr сокращает время сортировки в 2 раза (на этих данных - с 8 до 4 сек). Вот, что значит корректное обращение  :D  
Коды
Файл с миллионом элементов на листе на DropMe
Изменено: Jack Famous - 23.04.2019 17:26:35
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
4. Устав пытаться усовершенствовать ваш вариант квика
Ну это не мой вариант, а стыренный где-то здесь на форуме) И вообще "лучшее враг хорошего" (с).
Цитата
Jack Famous написал:
Если сможете что-то "допилить", то буду очень рад
Я вляпался в кап.ремонт и он сжирает всё время и все силы. Голова после точно не работает как надо. Может через месяц другой)
Цитата
Jack Famous написал:
(хоть и с ограничениями)
Видимо при попытке впихнуть Mid'ом в большую подстроку меньшую считываемая подстрока приравнивается к пустоте, или в случае сортера к набору пробелов.
Цитата
Jack Famous написал:
Получение уникальных словарём занимает всего 1 сек (на 1 млн!!!)
И это странно, т.к. у меня уже после 100к скорость заполнения словаря резко падала, причем в разы. Но если есть способ заставить работать словарь шустрее, то всякие подобные варианты извлечения уников и не нужны.
 
Цитата
Anchoret: стыренный где-то здесь на форуме
а я его вот тут видел))
Цитата
Anchoret: лучшее враг хорошего"
или всё-таки "дорога возникает под ногами идущего"?  ;)
Цитата
Anchoret: у меня уже после 100к скорость заполнения словаря резко падала, причем в разы
всё верно, только не после 100к элементов исходного массива, а после 100к уникальных элементов. Вот я сейчас прогнал по целочисленному массиву, в котором из миллиона исходного массива 976к уникальных — словарь работал 40 секунд, а квик 2 (!!!) секунды. Походу стек переполняется или вроде того. Попробую прикрутить какие-нибудь понты к словарю :D
Цитата
Anchoret: Видимо
я там вообще немногое понял))
Цитата
Anchoret: Может через месяц другой
удачного ремонта! Буду ждать)) пока сам чё-нить покумекаю
Изменено: Jack Famous - 23.04.2019 18:43:43
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Страницы: 1
Наверх