bedvit написал: нужно разобратся в каком варианте это происходит.
там на скрине1 видно в Immediate - 2x массив уже даёт сбой out of memory... а потом ошибка IVBA Failed уже начинает появляться при новом запуске... я кстати полистала ту книгу в главе COM - и мне всё-таки кажется, что при ошибке out-of-memory что-то корректно не закрывается или не удаляется из памяти - вот и получается при повторном вызове IVBA Failed... возможно, ошибка как раз в интерфейсе IUnknown, который обеспечивает доступ к клиенту через 3 метода QueryInterface, AddRef, Release, которые потом (будучи виртуальными методами) переопределяются для взаимодействия с классом COM'a... т.е. то ли счётчик AddRef не обнуляется (не знаю, важно ли), то ли Release корректно не отрабатывает, освобождая доступ к COM'у (клиент ведь не может удалить указатель на интерфейс, но как-то его должен освободить,наверно, чтобы повторное подключение к этому интерфейсу с этого клиента могло состояться)... вобщем не знаю - не видела вашу реализацию интерфейса IUnknown только сам класс вы выложили (насколько поняла) и интерфейс IDispatch для передачи параметров... имхо... и вообще, честно говоря, ещё только знакомлюсь с этим языком... p.s. да у меня x32 - но я и брала версию для x32... p.p.s вариант по сути и нужен 2x массив... но в любом случае если есть проблема, интересно ведь разобраться - на проблемах обычно и учимся в реализациях задач
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
bedvit написал: (сделал два алгоритма - по Excel и по Юникоду).
разница подходов здесь спасибо посмотрю, но у меня пока x32... я в Access - перекидываю из RS результат запроса в массив - и над алгоритмом ещё не думала - использовала вашу надстройку ArraySort2... тестово - ок с текстом... с числами надо ещё подумать... и с датами... но мне, наверно, первостепенно с текстом, потом датами, потом long, потом double... а вообще, наверно можно подумать про создание Template и использование его для разных типов... хотя по нескольким (разных типов) полям - будет, наверно, нелегко сортировать... чисто алгоритмически ещё не совсем представляю... но вот Templates уж очень интересными кажутся подумаю на досуге... p.s. я пока ещё только учусь читать templates в библах... потом, наверно, можно будет пробовать и писать свои...
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
JeyCi, благодаря вам нашел две! утечки памяти, дыры заделаны, память в безопасности.
Цитата
JeyCi написал: с числами надо ещё подумать... и с датами... но мне, наверно, первостепенно с текстом, потом датами, потом long, потом double... а вообще, наверно можно подумать про создание Template и использование его для разных типов...
Уже! это и есть VARIANT - сортировка любого типа данных, который он инкапсулирует. Тестируйте... залил новые библиотеки со всеми изменениями. Здесь описание нового метода и Компаратор (алгоритм сравнения)
bedvit написал: Уже! это и есть VARIANT - сортировка любого типа данных, который он инкапсулирует.
bedvit, гениально!!! буду тестить... отпишусь спасибо! - а то ваша надстройка - очень полезная вещь! особенно для Access -т.к. даёт возможность его медлительные шаги перенести на сторону клиента (и выполнять с невероятно быстрой скоростью) - т.е. в коде VBA (в качестве клиента)
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
честно говоря у меня не сортирует по 3-му столбцу - см. файл Access... и по нескольким тоже (но второе, как я поняла, ещё не заложено в этой версии?) (по Первому - даты - OK) === в XL выводы в файле - ошибка IVBA Failed выскакивает, когда не хватает памяти, но не появляется снова при уменьшении рабочего размера arr... хотя он у меня такой большой и не бывает... просто резюмировала для инфо...
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
Тест вашего файла на win7x64 Excel2016x64 5 млн строк Простая сорт. STRING 1х массива, по возрастанию (по умолч.): 0,7460938 сек. Простая сорт. VARIANT 1х массива, по возрастанию (по умолч.): 0,96875 сек. Простая сорт. VARIANT 2х массива, по возрастанию (по умолч.): 1,625 сек.
10 млн.строк Простая сорт. STRING 1х массива, по возрастанию (по умолч.): 1,703125 сек. Простая сорт. VARIANT 1х массива, по возрастанию (по умолч.): 2,074219 сек. Простая сорт. VARIANT 2х массива, по возрастанию (по умолч.): 3,628906 сек.
При этом оперативки на все процессы уходит больше 2 Гб (больше 4 на всю систему). видимо поэтому и вылетает, не хватает адресного пространства в х32. Переходите на х64 - ни одного вылета замечено не было.
bedvit написал: на все процессы уходит больше 2 Гб
мне пока столько не надо 2млн - я больше 1000 сортировать не буду наверно ещё долго... просто тестово показала - что после ошибки на др объёме возвращается нормальная функциональность - спасибо!... а скорость, действительно, феноменальная!.. при работе с памятью напрямую... только закрывать надо ненужные приложения - чтобы не отнимали память кучи...
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
всё работает на разных типах данных по одному столбцу... может быть, вас не затруднит (как будет время) вернуть функционал для сортировки по нескольким столбцам (не только key_1)... и выложить вариант COM только для сортировки (ведь если библа динамически подключается - наверно быстрее подключается и меньше по памяти, если только нужное т .е. сортировка)... заранее спасибо... и уже спасибо за всю проделанную работу!.. respect... ваш код, по ходу, не на чистом C++, а на C в бОльшей степени - насколько понимаю... и это пока более сложный вариант для меня, чем чистый C - спасибо за пример (части) кода... а по поводу алгоритма, тоже насколько понимаю, через Unicode быстрее??... это видимо wchar_t в общем случае? p.s. и можно уточнить по поводу утечек памяти насколько понимаю, чтобы их избегать - надо успевать удалять объекты в деструкторе ДО того, как указатель на них уходит(пропадает) из зоны видимости? и ещё лучше самим удалять указатель - чтобы не было таких пропаж?.. как это правильно делать? в какой части кода? примерно пару строк примера правильной последовательности удаления/очищения памяти, если можно?... чтобы не мучаться с этим до конца жизни... наверно, в деструкторе?
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
JeyCi написал: примерно пару строк примера правильной последовательности удаления/очищения памяти, если можно?... чтобы не мучаться с этим до конца жизни...
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
bedvit написал: теперь в ArraySortV три ключа сортировки . Тестируйте.
bedvit, спасибо ещё раз! и за наводку резкости...
Цитата
bedvit написал: нужна практика и теория, понимание механизма выделения и освобождения памяти
на кибер уже заглянула ... наверно, действительно остальное нарабатывается опытом... просто интересно, вы на глаз (по памяти своей) считаете/замечаете, сколько утекло?.. или это как-то промониторить можно в IDE?.. или просто интуитивно и методом тщательной вычитки своего кода?.. (чтобы в принципе заметить, что уже утекло)... это, наверно, последний интригующий вопрос к вам, как к спецу...
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
в принципе ОК... только порядок сортировки один для всех ключей - но это уже детали... уже ! намного ! легче будет работать с данными выгрузки из Access... всем смело рекомендую вашу работу и ваш профессионализм!.. и благодарю за внесённый вами, для юзеров XL наверно ещё непосильный, но очень ювелирный и важный вклад в эту ветку - для user friendly работы с Access... perfect
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
Утечку памяти видно в профилировщике, в диспетчере задач по текущему процессу, в коде. Окончательная шлифовка - тестированием. Направление сортировки сейчас задаётся для трех ключей. Есть задачи, когда бывают противоположные? С double завтра посмотрю что там, с ним.
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
JeyCi, у меня все сортируеn (у вас - по убыванию) вот результат из вашего макроса: Простая сортировка 2х массива: 2,761719 сек. mark jpy jpy gbp gbp euro euro chf chf cad aud
там в результате Debug в Immediate по трём столбцам в моём файле-примере... и видно на примере chf (когда сортируем по 1.3.4 столбцам) и как противоположно - eur (или jpy - на вскидку не помню точно)... когда 4-й столбец на месте key_3 - то нет сортировки - сравнить chf и jpy и eur... поставила его на место key_2 - вроде норм
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
bedvit, простите, сглупила в последнем тесте - там же по первому полю шла сортировка а потом 4-ое сортировалось в рамках первой сортировки и второй... вобщем там правильно всё работало - sorry... новый ещё посмотрю
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
Пользуйтесь. Пишите если будет незадокументированное поведение, ошибки, вылеты. Я со своей стороны тоже протестировал,и обычно так делаю перед релизом. Таковых пока не нашел.
Так же для возможности сортировать строки или столбы - сделал новый функционал в библиотеке: Transpose- быстрое транспонирование двухмерного массива (на месте).
Код
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 ArrV2: ReDim ArrV2(-5 To testSize, -2 To 3)
For i = 0 To testSize
ArrV2(i, 0) = Format$(Int(Rnd * 1000), "0000")
ArrV2(i, 1) = Format$(Int(Rnd * 1000), "0000")
ArrV2(i, 2) = Format$(Int(Rnd * 1000), "0000")
Next
'стандартный
arrTmpV = ArrV2
t = Timer
arrTmpV = Application.Transpose(ArrV2)
Debug.Print "Application.Transpose: " & Timer - t & " сек."
'библиотека
arrTmpV = ArrV2
t = Timer
bVBA.Transpose arrTmpV
Debug.Print "bVBA.Transpose: " & Timer - t & " сек."
'библиотека - лист
arrTmpV = [a1:j20]
t = Timer
bVBA.Transpose arrTmpV
Debug.Print "bVBA.Transpose - Лист" & Timer - t & " сек."
[m1:af10] = arrTmpV
End Sub
Результат Application.Transpose: 3,207031 сек. bVBA.Transpose: 0,140625 сек.
+ Application.Transpose не выводит более 34 тыс столбцов.
кстати очень хорошая идея! - а то RS.GetRows всегда приходится транспонировать для нужного вида... в ADO... Спасибо p.s. правда в DAO у меня пока почему-то берётся только 1-ая запись... поэтому там в коде на быструю руку набросала пример с пробежкой по RS'у... буду смотреть
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
JeyCi написал: правда в DAO у меня пока почему-то берётся только 1-ая запись...
всё взялось, но Application.Transpose не выполняется в Access, как в Excel обычно... в принципе можно и руками (всё отразила в файле)... но с надстройкой, конечно, намного легче... и верю на слово что на больших объёмах быстрее... правда жаль, что вы в 1.0.1.4. вернули сортировку к прежнему виду - по умолчанию по нулевому столбцу по убыванию - вобщем всё по умолчанию, насколько поняла... вариант в приложенном файле
Скрытый текст
Код
Option Compare Database
Sub Test_arr_sort()
'зарегистрирован в реестре и подключён в Tools-Reference
'Dim a As BedvitCOM.VBA: Set a = New BedvitCOM.VBA
Dim arr As Variant '() As String
Dim bVBA As Object
Dim rs As Recordset
Set bVBA = CreateObject("BedvitCOM.VBA")
Set rs = CurrentDb.OpenRecordset("q")
rs.MoveLast
n = rs.RecordCount: Debug.Print rs.RecordCount & vbCrLf
rs.MoveFirst
arr = rs.GetRows(n)
rr = UBound(arr, 2) + 1
cc = UBound(arr, 1) + 1
'arr_trans = Application.Transpose(arr) 'in Access vba - ERROR...
'перекладывать надо руками:
ReDim arr_trans(0 To rr - 1, 0 To cc - 1)
Debug.Print "arr_trans manually:" & vbCrLf
For i = 0 To rr - 1
For j = 0 To cc - 1
arr_trans(i, j) = arr(j, i)
Next
Debug.Print arr_trans(i, 2) & " - " & arr_trans(i, 0) & " - " & arr_trans(i, 3)
Next
Debug.Print vbCrLf
'===============
arrTmp = arr
'библиотека С/С++
Debug.Print "Транспонирование библиотекой C/C++"
t = Timer
bVBA.Transpose arrTmp
Debug.Print "bVBA.Transpose: " & Timer - t & " сек." & vbCrLf
'осталась только сортировка по умолчанию по 0-му полю ASC...???
Debug.Print "Сортировка библиотекой C/C++"
Debug.Print "Сортировка только по умолчанию (!) по 0-му полю ASC"
t = Timer
bVBA.ArraySortV arrTmp
Debug.Print "bVBA.ArraySortV: " & Timer - t & " сек." & vbCrLf
'DEBUG.Print
For i = 0 To UBound(arrTmp, 1)
Debug.Print arrTmp(i, 2) & " - " & arrTmp(i, 0) & " - " & arrTmp(i, 3)
Next i
Set bVBA = Nothing
End Sub
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
JeyCi написал: жаль, что вы в 1.0.1.4. вернули сортировку к прежнему виду
не совсем понял, что я вернул осталось все как было, просто добавился функционал с 3мя ключами. Если ключей нет, берется первый столбец, если есть- берутся указанные ключи. если ключ один, сортируется по одному, два - по двум и т.д.
проверила ещё раз всё... вижу - просто после транспонирования размерности в arrTemp от нуля, но в сортировке счёт ключей от 1 - вот и затупила немного...sorry thanks! так работает:
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
изучаю ваш класс Сортировки: вижу не совсем знакомые слова - CComBSTR и CComSafeArray - насколько понимаю - это Классы (которые где-то тоже надо описать)?, и concurrency - видимо, библа, из которой используем метод parallel_buffered_sort?, и вот сама сортировка по нескольким полям
Код
//сортируем двухмерный массив по одному из измерений (столбец - сортировка строк)
long cElements_full2 = cElements_0 * cElements_1;
std::vector <BSTR> vBSTR(pbstr, pbstr + cElements_full2); //передаем в вектор
for (long i = 0; i < cElements_0; i++) {
for (long j = 0; j < cElements_1; j++) {
pbstr[j + i * cElements_1] = vBSTR[out2[j] + i * cElements_1];
}
}
алгоритм пока не совсем могу понять?... помню, что BSTR - ссылочный тип... а откомментировать логику этих строк для себя не совсем могу... это с учётом того, что чуть выше мы задали последовательность ключей через Append ...
Код
CComBSTRtmp.AppendBSTR(pbstr[i + offset3])
понимаю (допускаю, что раньше с таким вообще не встречалась), что сортируем по сути ссылки (исх. массив стоит на месте)... но вот, вопрос - ? как из этих строк он (код) понимает, что надо сортировать каждую следующую размерность в рамках предыдущей?? - при всём том, что цикла вокруг не вижу (который шёл бы по всему, что мы Append-или, простите за выражение)... грешным делом, уже думаю, может это какая bubble_sort но на ссылках и всё проще, чем я не могу прочитать... хотя не совсем похоже на неё... да и вы уже предупреждали - параллельные алгоритмы сортировки может вас не затруднит ещё поправить мои комменты к этим строкам?.. смысл cElements_full2 = cElements_0 * cElements_1 - это количество всех элементов в массиве... pbstr - это ссылка на 1-й элемент... pbstr + cElements_full2 - весь вектор, в который передали... весь исходный массив? какой-то он линейный? не двумерный? (или ссылкам всё равно? наверно, можно и так!) и идём циклом по строкам и столбцам... делая такое:
Код
pbstr[j + i * cElements_1] = vBSTR[out2[j] + i * cElements_1];
вопрос - что мы делаем?? может, слева - это что-то из адресной арифметики? а справа - это значение из выходного массива (который, наверно, выше создавался по размерам входного) и мы просто ставим нужный элемент на нужное место в out2?.. но как в таком случае получается сортировка в рамках последовательности заданных 1.2.3 полей?.. если цикла нет по ним (т.е. тому, что наAppend'или)? может вопросы немного дилетантские?.. а может я чего-то не вижу в коде?.. не хватает мне цикла по полям сортировки! - даже если я поверю в адресную арифметику - только поверю - может вы сориентируете на какой линк и по ней (если она здесь нужна)... всё равно, не вижу, как мы обходимся без цикла по полям_сортировки ?? а просто одним ходом справляемся со всеми Appended полями для сортировки??
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
JeyCi написал: CComBSTR и CComSafeArray - насколько понимаю - это Классы (которые где-то тоже надо описать)?, и concurrency - видимо, библа, из которой используем метод parallel_buffered_sort?
смотрите справку microsoft. Это стандартные классы.
пишем в выходной массив нужный элемент по нужным индексам (полученным при сортировке)
Цитата
JeyCi написал: всё равно, не вижу, как мы обходимся без цикла по полям_сортировки ?? а просто одним ходом справляемся со всеми Appended полями для сортировки??