Страницы: Пред. 1 2 3 4 5 6 7 8 След.
RSS
Сортировка в двумерном массиве VBA Excel, Написал тут небольшую процедурку, может кому будет полезна
 
Цитата
Jack Famous написал:
Оказывается, текстовые ключи короче 3 символов — не срабатывают
У меня срабатывают:
Tester

Ну и раз полез в код, то заодно немного ускорил:
Скрытый текст
Изменено: Anchoret - 27.04.2019 14:40:02
 
Цитата
Anchoret: У меня срабатывают:
вполне возможно, что это я где-то косячнул при редактировании исходника. Всё-равно теперь уже буду тестить новый — спасибо большое)))
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Anchoret, приветствую!
Разбирали тут задачку одну, решил применить ваш сортер, а он зарылся прям конкретно — 216 (!!!) секунд сортировал (для сравнения, на тех же данных штатный сортировал 2 секунды, на более хаотичных - 4 секунды). Результат сортировки был корректен (вроде, т.к. проверял по количеству отмеченных ячеек). Массив (600,3), где 3ий столбец пустой (не знаю, играет ли это роль)…

Жду вас с нетерпением  :D
Изменено: Jack Famous - 19.05.2019 17:25:52
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Anchoret, приветствую!
В связи с ограничениями и нестабильностью текстового сортера, написал универсальный сортер двумерного массива на основе вашей рекурсивной процедуры.
КОДЫ
замечания и улучшения приветствуются
Изменено: Jack Famous - 24.05.2019 13:18:02
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
bedvit написал: Сортируйте в VBA и удаляйте дубликаты на скоростях С++ до 35 раз быстрее самого быстрого алгоритма (QuickSort) по типу данных: "String"
к #134
мои результаты тестирования ArraySort C++ от bedvit здесь - если что-то ещё появится отпишусь...
спасибо и respect за скорость и всю разъяснительную работу на форуме  8) - иначе оставались бы слепыми...
Изменено: JeyCi - 22.08.2019 11:29:38
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
JeyCi написал: мои результаты тестирования ArraySort C++
а мои тут и там разница уже не такая впечатляющая…
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Это потому, что
Цитата
Jack Famous, написал:
где я дополнительно перевожу в String и обратно в Variant

Да, сейчас сортируются только тип данных String.
Вот здесь я писал реализацию (код этого метода)
Там используется SafeArray (см. структуру) - String,
а что бы сортировать по VARIANT, мне нужно распилить вот эту структуру. Теперь прикиньте сколько это кода (посмотрев на тот первый). Это трудоемко и много времени, стоит ли оно того? на примере SafeArray (String) - пользуются пока несколько человек.
Изменено: bedvit - 22.08.2019 20:39:25
«Бритва Оккама» или «Принцип Калашникова»?
 
Виталий, ну неужели вы думаете, что я вам в упрёк это сказал? Просто я тестирую на более "реальных" для себя данных.
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous, да это все верно, мне просто печально смотреть на микроскоп, в сколах от гвоздей :) про  VARIANT дописал выше.
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, про микроскоп понимаю)) ну смотрите: данные у людей разные. Ветка: приводить к одному виду или иметь универсальный сортер (или набор). Далее идёт баланс между удобством применения и скоростью. Подключение надстроек и прочих нестандартных библиотек не очень удобно, плюс контроль версий, отлов ошибок и прочие прелести.

Сейчас есть этот текстовый сортер и для узкоспециализированных данных (текст) он на тестах дал выигрыш в 4 раза. На миллионе это несколько секунд (кажется около 6, я с телефона и глянуть неудобно). И это на пределе реальных данных программы.
Так вот, как по мне, при таких объёмах гораздо полезнее будет пересмотреть подход, чем выигрывать крохи на пределе. Если бы не было такой запары с обеспечением работоспособности, то я бы внедрил это АБСОЛЮТНО везде. Но это нестандартная библиотека…

Мой вывод: пока что разница во времени для пользователей незаметна, а геморроя сильно больше. Надо думать
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Начнём...

Цитата
Jack Famous написал:
запары с обеспечением работоспособности
Добавил проверку не открыта ли COM библиотека в другой программе (тогда не распаковываем, а используем уже загруженную). Тестируйте на ошибки.

Цитата
Jack Famous написал:
универсальный сортер (или набор).
Добавил сортировку VARIANT (теперь можно сортировать ЛЮБЫЕ данные)

По теме матчасть

Компаратор взял отсюда (пришлось правда подправить).

Итак новая функция
ArraySortV (Variant), старая будет переименована в ArraySortS (String) (пока называется по старому в отладочном варианте)
ArraySortV массив, порядок сортировки, номер столбца по которому сортируем
Можно сортировать массив, забирая прямо с листа (см. способ.3)

Библиотека Debug_BedvitXLL(x64).zip

Тест:
Код
Sub Test_arr_sort()
'Dim a As BedvitCOM.VBA: Set a = New BedvitCOM.VBA
Dim bVBA As Object: Set bVBA = CreateObject("BedvitCOM.VBA")
Dim testSize As Long: testSize = 2000000

Dim ArrV: ReDim ArrV(0 To testSize) As String
Dim ArrV1: ReDim ArrV1(0 To testSize)
Dim ArrV2: ReDim ArrV2(0 To testSize, 0 To 1)

For i = 0 To testSize
    ArrV(i) = Format$(Int(Rnd * 2000000), "0000000") '30% дубликатов
    ArrV1(i) = Format$(Int(Rnd * 2000000), "0000000") '30% дубликатов
    ArrV2(i, 0) = Format$(Int(Rnd * 2000000), "0000000") '30% дубликатов
Next

'0й способ по 1х массиву STRING
t = Timer
bVBA.ArraySort ArrV
Debug.Print "Простая сорт. STRING 1х массива, по возрастанию (по умолч.): " & Timer - t & " сек."

'1й способ по 1х массиву
t = Timer
bVBA.ArraySortV ArrV1
Debug.Print "Простая сорт. VARIANT 1х массива, по возрастанию (по умолч.): " & Timer - t & " сек."

'2й способ по 2х массиву
t = Timer
bVBA.ArraySortV ArrV2
Debug.Print "Простая сорт. VARIANT 2х массива, по возрастанию (по умолч.): " & Timer - t & " сек."

'3й способ - данные с листа
arrTmpV = [a1:b200]
t = Timer
bVBA.ArraySortV arrTmpV, 1, 1
Debug.Print "Простая сорт. VARIANT 2х массива, по убыванию, по первому столбцу: " & Timer - t & " сек."
[c1:d200] = arrTmpV

End Sub


Результаты на 2 млн. чисел:
Простая сорт. 1х массива, по возрастанию (по умолч.): 0,1953125 сек.
Простая сорт. 2х массива, по возрастанию (по умолч.): 0,375 сек.

Результаты на 2 млн. строк:
Простая сорт. STRING 1х массива, по возрастанию (по умолч.): 0,2734375 сек.
Простая сорт. VARIANT 1х массива, по возрастанию (по умолч.): 2,023438 сек.
Простая сорт. VARIANT 2х массива, по возрастанию (по умолч.): 2,234375 сек.
Видим что отставание от предыдущей функции существенное, т.е. есть куда оптимизировать.
Нужно оптимизировать в компараторе сравнение строк.

Ну что, тестируем?
Изменено: bedvit - 24.08.2019 21:38:42
«Бритва Оккама» или «Принцип Калашникова»?
 
Если переделать компаратор, под сортировку по юникоду, т.е.
сортировка в excel
Цитата
a
A
aaaa
aaaa
ABC
b
B
c
C

Сортировка по Юникоду (стандартная для С++ функция wcscmp):
Цитата
A
ABC
B
C
a
aaaa
aaaa
b
c
То скорость увеличивается почти на порядок и сравнивается с предыдущим решением на строках:
Простая сорт. STRING 1х массива, по возрастанию (по умолч.): 0,2578125 сек.
Простая сорт. VARIANT 1х массива, по возрастанию (по умолч.): 0,296875 сек.
Простая сорт. VARIANT 2х массива, по возрастанию (по умолч.): 0,5234375 сек.

Библиотека:  Debug_BedvitXLL(x64)-2.zip

Какой должен быть алгоритм сортировки (компаратор) и почему именно тот? Нужен ли 100% как в Excel?
Изменено: bedvit - 24.08.2019 22:56:01
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, приветствую!
ооох))) ну с такими вводными теперь нам точно придётся вернуться к разбору возможностей самораспаковки библиотеки без установки надстройки (тип делать файл "all-in-one" или "открыл и работаю" — для пользователей не особо настроенных что-то там подключать))

По теме: сортировка Excel мне не нравится в первую очередь из-за того, что на таком "отсортированном" массиве невозможно реализовать двоичный поиск стандартными методами. Я имею ввиду то, что условие arr(i)<=arr(i+1) там соблюдается далеко не всегда (даже, если выбирать сортировку с учётом регистра). В свою очередь, рекурсивная процедура такое неравенство обеспечивает, что позволяет производить супербыстрый поиск, что уже даёт очень большой прирост на 10k+ данных (пример отAnchoret тут).
Так вот… Если "Сортировка по Юникоду" обеспечивает неравенство для двоичного поиска (или сам поиск можно изменить для работы с такой сортировкой при сохранении скорости), то это именно то, что нужно  :idea:

По тестам: постараюсь сегодня хоть что-то протестировать

Огромное вам спасибо за реализацию, думаю, что вы с лёгкостью обгоните рекурсию. Отдельный респект за возможность работы с вариативной переменной в качестве массива (я так понял, раз arrTmpV = [a1:b200] не объявлена, то она вариативная).
Изменено: Jack Famous - 26.08.2019 09:06:20
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
разбору возможностей самораспаковки библиотеки без установки надстройки
не проблема.
Цитата
Jack Famous написал:
Если "Сортировка по Юникоду" обеспечивает неравенство для двоичного поиска
думаю это то, что вам нужно. Оставил именно сортировку по Юникоду. Лично мне это понятнее, чем сортировка в Excel, которая неясно (для меня) по какому принципу строится.
Цитата
Jack Famous написал:
(я так понял, раз arrTmpV = [a1:b200] не объявлена, то она вариативная).
именно так.

Создал тему Библиотека COM (OLE Automation). Часть 2 - ArraySort (Variant) где все описние по этому методу.
Тестируйте.
И залил новые библиотеки со всеми изменениями.
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit: это то, что вам нужно…сортировка в Excel…неясно…по какому принципу строится
отлично! Я тоже не понимаю  :D
Цитата
bedvit: Создал тему
я так понял, это "буферная" тема и потом библа всё-равно добавится в основное хранилище?
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
"буферная" тема и потом библа всё-равно добавится в основное хранилище?
в основном хранилище библиотеки включают все решения (классы, методы). В отдельных темах просто рассматриваются более подробно, с примерами, что бы хранилище не загромождать множеством разных подробностей.
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, а мне за такое тут атата делают)))
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
На самом деле я из нескольких решений собрал одну библиотеку, это удобно, весь функционал всегда при мне. Возможно и вам попробовать также сделать. Может вам так тонко намекают на это ) И для пользователей удобно.
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit: Может вам так тонко намекают на это
не похоже, ну да это всё ерунда :D
Вот тут выложил саму форму с поиском и перекрёстными ссылками хочу подтягивать инструменты на её основе. Пока что только фильтр (та ещё запара была) и вставка (просто). Посмотрите - об одном ли и том же мы говорим…

К сожалению, пока что не могу нормально потестить ваш новый сортер, т.к. висят серьёзные задачи и нужно плотно поработать, но я обязательно вернусь к этому как только вздохну посвободнее  ;)
Изменено: Jack Famous - 27.08.2019 08:38:07
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
На самом деле почти для всех задач в Excel хватает сортеров написанных на VBA. Если требуется что-то большее, то это уже задача для другого приложения) ИМХО

П.С.: Как вариант порыть другие языки или тот-же VB с целью создания приложения отвечающего всем нуждам и чаяниям с импортом/экспортом книг Excel.
 
Anchoret, с возвращением)
Я тоже об этом писал, но для личного пользования почему бы нет. Плюс спортивный интерес. Ну а когда обкатаем, то и в файлы внедрять можно с последующей самораспаковкой библиотек. Опыт, кстати, может впоследствии пригодится в установке любых других "неродных" библитоек
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous, следующим этапом будет написание сортера на ассемблере с указания дампа памяти в качестве входных параметров)
 
Всем привет! Согласен с обоими, ради интереса и знаний стоит разные варианты рассмотреть, хотя VBA на 99% закрывает потребности программиста для работы в Excel.
Anchoret, если получится написать на ассемблере, будет здорово! Посмотрим насколько можно будет прибавить в производительности. Хотя без оптимизаций под инструкции конкретного ЦП (SSЕ, AVX и т.д.), думаю выигрыш будет минимальный С++ и так компилируется в ассемблерный код. А современные компиляторы очень хорошо оптимизируют С++ код. Да и переносимость и универсальность будет под вопросом с написанными инструкциями под конкретный ЦП. Хотя резерв, конечно есть - это ГП (не только же биткоины майнить)
Изменено: bedvit - 27.08.2019 19:51:49
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, я врядли возьмусь за написание на базовом языке программирования) Последний раз писал на нем более 20 лет назад... Да и листинг такого сортера будет умопомрачительный. Поэтому полагаю, что самый быстрый из возможных вариантов сортировки будет предложенный Вами в текущей или будущей реализации)
 
Цитата
Anchoret написал:
Последний раз писал на нем более 20 лет назад
Здорово, а я мало практикую. Уважаю спецов ассемблера. Не тянет что-либо пописать, вспомнить былое?
Цитата
Anchoret написал:
Да и листинг такого сортера будет умопомрачительный.
Ради интереса глянул, 320 строк против 2085, итого в 6,5 раз длиннее, с учетом вызовов функций - call, без разворачивания листинга этих функций на ассемблере (что значительно сокращает листинг), но включая исходный код С++ (что немного удлиняет листинг).
Код ArraySortS на С++
Скрытый текст
Изменено: bedvit - 27.08.2019 23:26:04
«Бритва Оккама» или «Принцип Калашникова»?
 
Дизассемблированный код (выдает компилятор в Debug версии х64) ArraySortS+ исходный
Скрытый текст
...
Изменено: bedvit - 27.08.2019 23:20:23
«Бритва Оккама» или «Принцип Калашникова»?
 
Продолжение...
Скрытый текст
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, набор процессорных команд сильно изменился, список регистров тоже наверняка расширился + разные макрофункции и пр.) Полистал предложенный листинг - более половины не понятно, т.е. незнакомые команды и т.д.. Ну и также видно, что компилятор накопипастил все вызываемые функции , т.е. много повторяющихся участков кода. Полагаю, что вручную такое никто писать бы не стал - подпрограммы, условные переходы и пр., как вариант.
 
Anchoret, спасибо за комментарии к листингу. Познавательно. Это Debug версия, для Release версии, думаю компилятор оптимизирует часть кода, но руками конечно можно сделать лучше. Но писать 2 тыс строк, вместо 300 для одного метода - трудоёмкая задача. Видимо поэтому руками пишут только ключевые участки в коде, короткие программы, драйвера и т.п. Слишком дорого обходится код в человеко-часах. А на VBA это наверное вообще пару десятков строк. Хотя листинг на ассемблере будет длиннее чем мой. Разные скорость разработки, производительность, сложность кода (уровень вхождения). Я понимаю, что на ассемблере вряд-ли буду писать, язык относительно простой, но многое надо уметь держать в голове, безусловные переходы, ветвления, новые регистры, команды, архитектура ЦП. Пусть этим занимается компилятор :)
Изменено: bedvit - 28.08.2019 09:25:52
«Бритва Оккама» или «Принцип Калашникова»?
 
Anchoret, bedvit, и как всегда, мы ищем баланс между скоростью кода, его краткостью и универсальностью  :)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Страницы: Пред. 1 2 3 4 5 6 7 8 След.
Наверх