|
ArrayToString
|
|||
---|---|---|---|
#18+
Всех приветствую! Задача вроде простая - преобразовать строковый массив в одну строку, но наиболее быстрым способом. (ПБ8) Имеем массив порядка неск. сотен строк (100 метровый файл), на выхлопе нужна строка (нюансы обработки опущены). 1.PFC функция inv_string.of_ArrayToString() - жуткие тормоза; 2.Тупой цикл по элементам массива и сложение в результирующую строку - совсем немного быстрее (с увеличением строки все медленнеее цикл. Видимо менеджер памяти ПБ далеко не эталон); 3.Использование буферной переменной длиной 50000 символов (значение получено опытным путем) дает выигрыш в скорости раз в пять. Пока работает третий вариант, но нужно еще быстрее, Вопрос - как? Буду рад любым вариантам, (хоть через dw, хоть через диск, хоть на C вызовом из ПБ, хоть как, но надо быстрее) т.к. собственные мысли на исходе. Хелп. Спасибо. ЗЫ Двухядерный проц загружен на половину - есть мысли распараллелить, но это не панацея ... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 14:14 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
через ДВ dw1.object.data = sArray string sLine = dw1.object.data не помню уже синтакс (давно на ПБ уже писал) но мы примерно так делали правдо не уверен если это быстрее ... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 14:22 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
armblg, Если сервер базы позволяет, то может он вернет уже сформированную строку? ... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 14:29 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
Ikir, нет сервера в данном случае, просто работа с текстовыми файлами средствами ПБ (( ... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 14:41 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
armblg нет сервера в данном случае, просто работа с текстовыми файлами средствами ПБ (( То есть вы хотите ускорить операцию чтения из файла? А приведите код, формирующий буферную переменную. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 14:48 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
Ikirarmblg нет сервера в данном случае, просто работа с текстовыми файлами средствами ПБ (( То есть вы хотите ускорить операцию чтения из файла? А приведите код, формирующий буферную переменную. Нет. Чтение из файла выполняю при помощи ImportFile в дастору, что достаточно быстро. Именно массив в строку тормозит. Кода сию минуту под рукой нет, но примерно так; Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 15:19 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
В string нормально умещается 32 Kb так что делать Length лучше как-то убрать, возможно будет быстрее, вы же не будете каждый раз высчитывать длину строки И может быть просто в цикле пройти по datastore не загоняя в промежуточный массив ... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 16:03 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
spas2001В string нормально умещается 32 Kb так что делать Length лучше как-то убрать, возможно будет быстрее, вы же не будете каждый раз высчитывать длину строки И может быть просто в цикле пройти по datastore не загоняя в промежуточный массив Согласен, вычислять длину нужно к примеру раз в 1000 итераций (код сокращен), но скорости это не прибавляет почти(( Цикл по датасторе и считывание из каждой ячейки медленнее работы с массивом, данные в который загоняются одной командой, это проверено. Причем GetItemString() быстрее чем dot notation, хотя в книжках обычно утверждается обратное. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 16:14 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
Добавлю еще что изменение размера буфера с 30000 до 60000 особых результатов так же не дает, за этими границами скорость падает(( ... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 16:18 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
Скорость деградирует из-за того что при каждом добавлении строки результат получается копированием из старой строки, а она постоянно растет. Попробуйте следующий прием. 1) Пройтись в цикле по массиву и рассчитать суммарную длину строк 2) Выделить blob таким размером: lbb = blob(space(ll_total_len)) 3) Пройтись в цикле по массиву и используя BlobEdit вставить каждую строку в ее позицию в блобе. 4) Преобразовать блоб в конечную строку ls_res = string(lbb) ... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 16:34 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
Вариант интересный, должно работать быстрее ... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 16:37 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky, Спасиб за свежую идею, обязательно попробую и отпишусь, но вероятно уже после праздников. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 16:46 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
Anatoly MoskovskyСкорость деградирует из-за того что при каждом добавлении строки результат получается копированием из старой строки, а она постоянно растет. +1 Я бы попробовал: 1.Каким-нибудь sed-ом убрал из файла символ конец строки 2.Fileread-ом в режиме !Stream загнал бы в блоб по максимальным порциям( в PB6 32К) 3.Преобразовал блоб в string. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 16:54 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
Anatoly MoskovskyСкорость деградирует из-за того что при каждом добавлении строки результат получается копированием из старой строки, а она постоянно растет. Попробуйте следующий прием. 1) Пройтись в цикле по массиву и рассчитать суммарную длину строк 2) Выделить blob таким размером: lbb = blob(space(ll_total_len)) 3) Пройтись в цикле по массиву и используя BlobEdit вставить каждую строку в ее позицию в блобе. 4) Преобразовать блоб в конечную строку ls_res = string(lbb) Я пробовал аналогичную идею с Replace'ом - у меня получилось дольше чем тупо склеить. К тому же с такими объемами данных PB начинает клинить. Можно было бы склеивать как-то таким образом - склеить 2 строки в 1, оставшиеся (в 2 раза меньше) склеить 2 в 1 и т.д. (таким образом минимизируем количество склеек больших строк), но PB от такого у меня просто валится... ... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 17:00 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
IkirAnatoly MoskovskyСкорость деградирует из-за того что при каждом добавлении строки результат получается копированием из старой строки, а она постоянно растет. +1 Я бы попробовал: 1.Каким-нибудь sed-ом убрал из файла символ конец строки 2.Fileread-ом в режиме !Stream загнал бы в блоб по максимальным порциям( в PB6 32К) 3.Преобразовал блоб в string. Зря смеетесь, с памятью действительно так и есть(( Чтение из файла в любом случае получается медленне чем Импортфайл в датастору, и потом мне обязательно нужна обработка строк, поэтому массив или датастора необходимы, а строка нужна только на выходе. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 17:04 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
Быстрее всего будет модификация моего предыдущего варианта с использованием внешних функций. 1) Рассчитать суммарную длину строк во внешней ф-и №1 2) Выделить строку с таким размером 3) Во внешней ф-и №2 заполнить эту строку из массива Вот примерный код этих внешних ф-й Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31.
... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 17:42 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
armblg Чтение из файла в любом случае получается медленне чем Импортфайл в датастору, и потом мне обязательно нужна обработка строк, поэтому массив или датастора необходимы, а строка нужна только на выходе. С учётом этого, и того факта, что строковые операции в РВ - самые медленные, я бы развил идею Анатолия ещё дальше, а именно - после вышеуказанной обработки строк в датасторе (обязательно нужна :-)), делать datastore.SaveAS в файл, а уже этот файл обрабатывать специально написанной DLLкой, которая и выдаст склеенную строку. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 18:30 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
Филиппделать datastore.SaveAS в файл, а уже этот файл обрабатывать специально написанной DLLкой, которая и выдаст склеенную строку. Ну в данном случае думаю что получение строкового столбца DS через DOT нотацию в массив строк будет существенно быстрее чем SaveAs + чтение из файла в DLL. Код: plaintext 1. 2. 3. 4.
... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 19:09 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
Имхо, вариант с внешними функциями довольно перспективен. Очень надеюсь на достойную скорость. Проверю, как уже говорил, позже. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.05.2010, 19:50 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
Сравнил три варианта для контрастности оценки: 1 - через BlobEdit, 2 - через внешние С функции, 3 - как былО. Загонял два файла 44М и 88М в массив, потом массив в строку. Время засекал только для преобразования массива в строку. Итак: 44М 1) 1.9 сек; 2) 0.25 сек; 3) 45 сек. 88М 1) 3.9 сек; 2) 0.5 сек; 3) 175 сек + жуткий своп. Налицо преимущество использования внешних функций, но вариант с BlobEdit тоже порадовал скоростью, не ожидал. К сожалению последнее преобразование ls_res = string(lbb) для 88М файла валит програму - приходится преобразовывать частями что замедляет. В общем, всем спасибо за участие. Anatoly Moskovsky спешиал сенкс за идеи и примеры С-шных функций, при моем довольно слабом С они были кстати. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.05.2010, 18:08 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
armblgК сожалению последнее преобразование ls_res = string(lbb) для 88М файла валит програму - приходится преобразовывать частями что замедляет. Скорее всего это связано с тем что к тому моменту память процесса уже фрагментирована настолько что невозможно выделить непрерывный кусок нужного размера. Само преобразование ls_res = string(lbb) при достаточной памяти работает и на сотнях МБ ... |
|||
:
Нравится:
Не нравится:
|
|||
11.05.2010, 19:28 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
armblg , а что вы имеете ввиду под " обработкой строк "? Предчувствую, что там тормоза должны быть намного круче, чем процесс который их собирает потом в одну строку. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.05.2010, 00:25 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
AIS armblg , а что вы имеете ввиду под " обработкой строк "? Предчувствую, что там тормоза должны быть намного круче, чем процесс который их собирает потом в одну строку. К счастью, в данном случае когда такой большой объем, обработка минимальна - некоторые строки пропустить, вырезать какие-то символы, в общем мелочевка по сравнению с временем формирования строки, которое было первоначально. При более сложных обработках размер результирующей строки мал и Пб приемлимо быстро ее выполняет. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.05.2010, 07:32 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky, Возможно что и так, хотя с чего бы вдруг? Память выделена одним куском, и запись идет по определенным адресам, при преобразовании в строку достаточно еще раз выделить сравнимый объем. Это много дешевле сложения огромных строк в памяти когда там наверняка каша, однако ничего не валится. Может это в старенькой восьмерке ограничения или баги. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.05.2010, 11:41 |
|
ArrayToString
|
|||
---|---|---|---|
#18+
armblgAnatoly Moskovsky, Возможно что и так, хотя с чего бы вдруг? Память выделена одним куском, и запись идет по определенным адресам, при преобразовании в строку достаточно еще раз выделить сравнимый объем. Это много дешевле сложения огромных строк в памяти когда там наверняка каша, однако ничего не валится. Может это в старенькой восьмерке ограничения или баги. Не умеет PB нормально работать с памятью. Криво все работает и постоянно падает в любом месте. 11 например падает при выражении s1 = s + s + s + s + ... + s, когда в s строка в 1 МБ а количество сложений порядка 50-60. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.05.2010, 12:09 |
|
|
start [/forum/topic.php?fid=15&msg=36617920&tid=1335956]: |
0ms |
get settings: |
8ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
52ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
58ms |
get tp. blocked users: |
1ms |
others: | 13ms |
total: | 167ms |
0 / 0 |