Страницы: Пред. 1 2 3 4 След.
RSS
Как отсортировать 5 миллионов строк?
 
Цитата
Андрей VG написал:
Но показывать такое в примере я такого не буду
Я думал там только числа. Это случайно получилось. Прошу прощения.
 
Ека, господа, как у вас все медленно... 5 млн. строк это ниочем, вот если бы 55 млн. строк.
Изменено: bedvit - 28.06.2020 14:38:54
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
Jack Famous написал:
сколько будет?
Из #28 - 61 секунда, из #25 - 72 секунды. Мой с регулярками, если перейти на раннее связывание, 61 секунда тоже.
 
Здесь рабочий скрипт Рowershell. Если после последнего слеша вместо числа попадается слово, скрипт выдаёт предупреждение, но работу заканчивает. Может кому-то пригодиться.
Код
[IO.File]::ReadAllLines("c:\input.txt") | Sort-Object { [int64] ($_ -replace '.*/(\d+)$','$1') } | Set-Content .\output.txt
Изменено: georgmann - 28.06.2020 14:49:40
 
Цитата
bedvit написал:
как у вас все медленно
Привет, Виталий.
Увы, да. Основная проблема скорость чтения  и вставки в Recordset - 30 секунд (просто прочитать строки в массив 4 секунды) /записи 19 секунд. Почти 49  секунд из 61 непроизводительное IO. Ну, и регулярки - они тоже особо быстрыми не были.
Естественно, согласен, что привлечение Recordset тут лишнее - можно было бы и массивом записей озаботится и их через QuickSort упорядочивать. Но что делать с 23 секундами файловых операций, плюс регулярки?
Изменено: Андрей VG - 28.06.2020 14:57:38
 
Андрей VG, Привет. Да основное время это чтение/запись, у меня также в exe. Вообще часто всплывает сортировка в txt, наверное стоит добавить высокопроизводительный вариант в свою библу и поделится со всеми.
По данной теме можно удалить пару строк отсюда, собрать и будет довольно быстрое решение. Если ТС этот вариант подойдёт могу собрать. А вообще на 5 млн строк и предложенные решения вполне подходят, если не часто нужно сортировать.
«Бритва Оккама» или «Принцип Калашникова»?
 
Андрей VG, спасибо  ;)

UPD:
Вариант со скрина не выдерживает критики - Split строки, состоящей из 5 млн строк занимает 50 секунд  :D
Впрочем, логически это тоже было делать глупо…
Изменено: Jack Famous - 28.06.2020 15:44:41
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous, Алексей, у вас также Scripting.TextStream раза в два медленнее работает, чем старые древние методы VBA по работе с файлом?
 
Андрей VG, могу у себя протестировать, если есть тест)
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit написал:
если есть тест
Наваял. Путь лучше конечно прописать свой. У меня результаты. VBA напрочь уделывает Scripting, особенно на записи, правда, Scripting.TextSteam может писать ещё и в Unicode, но в данном случае IO с ANSI.
VBA Write: 5,988281
Scripting Write: 28,09375
VBA Read: 3,121094
Scripting Read: 7,730469

Excel 365 64bit, Windows 10, SSD
 
Цитата
Андрей VG: Scripting.TextStream раза в два медленнее работает, чем старые древние методы VBA
зато он позволяет сразу (без цикла) получить всю строку из файла и также сразу записать в него — возможно где-то сработает лучше
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
сразу (без цикла) получить всю строку из файла
Алексей, и что? Я так и не понял, откуда возникла эта мантра без цикла - это круто!
Дополним код
Код
Private Sub SingleStringRead()
    Dim t As Single, inputStr As String
    Dim fso As New Scripting.FileSystemObject, pStream As Scripting.TextStream
    t = Timer
    Set pStream = fso.OpenTextFile(FolderPath & "rows.txt", ForReading, False)
    inputStr = pStream.ReadAll
    pStream.Close
    Debug.Print "Scripting ReadAll: " & Timer - t
End Sub

И получим
Scripting ReadAll: 7,945313
Что с циклом, что без цикла - скорость у TextStream похоже не меняется :)
 
Цитата
Андрей VG: откуда возникла эта мантра без цикла - это круто
пардоньте-с — где я такое говорил?)))
Я считаю, что это просто удобнее и
Цитата
Jack Famous: возможно где-то сработает лучше
— то есть, разумеется, я ничего не утверждал…
Ты показал и доказал (спасибо), что этот вариант тормознутый — согласен, что мне проще засунуть этот цикл в UDFку (если уж так хочется краткости), для чтения и записи  ;)
Изменено: Jack Famous - 28.06.2020 17:27:39
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Jack Famous написал:
я ничего не утверждал…
Мало ли. Приношу свои извинения. Просто функциональный подход в программировании сейчас в моде. Я и сам его люблю, но не до абсурда же. Чаще всего строгое следование этому принципу в достаточно большом классе алгоритмов ведёт или к пожиранию памяти или, что хуже, к снижению быстродействия.

Updated.
Попробовал ADODB.Stream задействовать - вот где тормоза, так тормоза. Прибил через 5 минут ожидания. На всякий случай - вдруг я его как-то неправильно использую?
Код
Private Sub SingleAdoStreamRead()
    Dim t As Single, inputStr As String
    Dim pStream As New ADODB.Stream
    t = Timer
    pStream.Type = adTypeText
    pStream.Charset = "Windows-1251"
    pStream.Open
    pStream.LoadFromFile FolderPath & "rows.txt"
    inputStr = pStream.ReadText
    pStream.Close
    Debug.Print "Ado Stream ReadAll: " & Timer - t
End Sub
Изменено: Андрей VG - 28.06.2020 17:53:09
 
Внезапно… Вот за что я люблю программирование  :D
Несмотря на то, что сама сортировка аж в 5 раз медленнее (10 сек против 2, хотя у меня использовался универсальный сортер и специальный под целые числа был бы быстрее), общее время выполнения аж ровно в 2 раза быстрее (44 секунды против 88)
Выигрыш времени в основном на этапа обработки (почти в 5 раз)
Код
Андрей VG, благодарю за науку и тесты!  :idea:   8)
Изменено: Jack Famous - 29.06.2020 09:56:08
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Андрей VG написал:
ADODB.Stream задействовать - вот где тормоза, так тормоза.
Добрый день, коллеги! Андрей, сам по себе ADODB.Stream довольно шустрый, за исключением использования ReadText для экстремальных объемов. Файл из данной темы в 290 МБ он читает за 0,5 сек. Тормоза при использовании ReadText, как всегда, связаны с алгоритмами выделения памяти и отражены в документации. При использовании рекомендуемого разработчиком буфера в 128 К у меня метод ReadText отработывает за 1,4 сек без накопления (конкатенации) результирующей строки в Excel. Для накопления результата нужны трюки типа предварительного выделения памяти для результата и использования оператора Mid для изменения подстрок результата, тогда время - 2,9 сек. Без этих трюков время не приемлемo - порядка 400 сек.
Изменено: sokol92 - 28.06.2020 20:43:09
Владимир
 
Цитата
sokol92 написал:
Для накопления результата нужны трюки типа предварительного выделения памяти для результата и использования оператора Mid для изменения подстрок результата, тогда время - 2,5 сек
Владимир, большое спасибо. Хоть и не пользуюсь, но возьму на заметку.
 
Андрей VG, Андрей, вот мои результаты:
VBA Write: 13,71875
Scripting Write: 46,95313
VBA Read: 5,023438
Scripting Read: 13,23438

Скрытый текст

Без оптимизаций сортировка файла из сообщения21 - 15,5 сек. (сама сортировка 4,7 сек)
Файл - пример прилагаю. Файл txt выкладывал на D:, измените в макросе на свой путь и готово.
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, ещё в 3 раза быстрее — ну тут я не сомневался  8)
Антивирус взъерепенился, отправил на проверку и уже потом дал добро :D
Изменено: Jack Famous - 29.06.2020 06:41:57
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
bedvit, большое спасибо, за реализацию. Только, приношу свои извинения, может не строки тогда сортировать, а индексы? Иначе, получается, пусть ваш ПК в два раза медленнее чем у Алексея. Тогда Recordset выполнил сортировку за 4 секунды, а у вас получилось 4,7 секунды.
 
Добавлю еще вариант решения с использованием SQL. В примере исходный файл (file.txt) и результат (result.txt) находятся в папке D:\temp, там же создаем файл schema.ini со следующим содержимым:
Код
[file.txt]
ColNameHeader=False
Format=Delimited(/)
CharacterSet=1251
TextDelimiter="none"
Col1=clm1 Text
Col2=clm2 Text
Col3=clm3 Text
Col4=clm4 Text
Col5=clm5 Text
Col6=clm6 Long
Col7=clm7 Text
MaxScanRows=0

[result.txt]
ColNameHeader=False
Format=Delimited(/)
CharacterSet=1251
TextDelimiter="none"
Col1=clm1 Text
Col2=clm2 Text
Col3=clm3 Text
Col4=clm4 Text
Col5=clm5 Text
Col6=clm6 Long
Col7=clm7 Text
MaxScanRows=0
код VBA
Код
Sub TextFileSort()
    Dim objRS: Set objRS = CreateObject("ADODB.Recordset")
    objRS.Open "SELECT * INTO [result.txt] FROM [file.txt] IN 'D:\temp' 'TEXT;HDR=No;FMT=Delimited;' ORDER BY [clm6]", "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\temp;Extended Properties=TEXT"
End Sub
Изменено: DenSyo - 29.06.2020 11:23:01
 
Jack Famous, рад, что вирусов не нашлось) Хотя, если бы вирус нашелся, а я его не писал, значит появился ИИ. Это Нобелевка, эх...
Андрей, а так (комп помощнее, вчера домашний, сегодня рабочий)?
Использовал параллельную сортировку concurrency::parallel_sort
Итого 4,4 сек
Файл не влезает, пробую уменьшить. Все, влез.
Изменено: bedvit - 29.06.2020 11:40:01 (добавил файл)
«Бритва Оккама» или «Принцип Калашникова»?
 
DenSyo, время выполнения какое?

Цитата
bedvit: рад, что вирусов не нашлось
если что, антивирус сам отправил - я-то не сомневался в вас  :D
Изменено: Jack Famous - 29.06.2020 10:51:41
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
время выполнения какое?
на моей машине 63 сек. пример Андрея из #29 показал у меня 86
Изменено: DenSyo - 29.06.2020 11:02:32
 
Цитата
bedvit написал:
Итого 4,4 сек
Вот! теперь видно что это С++.  Супер!
DenSyo,  каков порядок вывода будет для hpps://server/blabla/1000000 и hpps://server/blabla/20 - оценивали в своём решении?
Изменено: Андрей VG - 29.06.2020 11:10:41
 
DenSyo, у меня (из #45) 44 сек - может можно как-то оптимизировать запрос для скорости?
я совсем не буб-бум в этом конечно, но вроде рекордсет для этого плох - типа запрос можно как-то по-другому отправить и будет быстрее
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Добавил файл в сообщение 52, протестируйте на время - интересно.
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
каков порядок вывода будет для hpps://server/blabla/1000000 и hpps://server/blabla/20 - оценивали в своём решении?
Хорошее замечание, Андрей. Поправил schema.ini
Цитата
Добавил файл в сообщение 52, протестируйте на время - интересно.
у меня 4,577 - шустро канеш
Изменено: DenSyo - 29.06.2020 11:36:34
 
В свое время реализовывал сортировку слиянием, где текстовый файл разбивался на блоки, каждый первоначальный блок который влезает в память сортировался быстрой сортировкой, затем блоки сортировались слиянием
Под текущую задачу нужно менять код (вырезать хвост и по нему делать сравнение), но метод интересен тем, что не ограничен в размере файла (количестве элементов), можно и несколько гигабайт отсортировать, самым медленным здесь будут дисковые операции.
Реализовано на Freebasic (легко перевести на VBA)

Есть генератор случайных строк (задаем количество случайных элементов) и сама сортировка, см. вложение
По скорости сортировка получилась не очень быстрой, но может кому нибудь пригодиться
 
Цитата
bedvit написал:
интересно.
Виталий, протестировал. Скорость загрузки выгрузки - впечатляет, а вот сортировка не очень. Самый быстрый получившийся код (костыльно, но времени на доводку не хватает)
Скрытый текст

Выполнение:
Read time: 12,90625
Sort time: 6,796875
Write time: 8
Full time: 27,70703

MCH, Михаил, большое спасибо, всё никак не освою, а тут такой повод разобрать наконец-то.
Страницы: Пред. 1 2 3 4 След.
Наверх