| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > Посчитать строки в текстовике |
| Автор: Витаминка 27.12.2006, 06:07 |
| Привет! С праздником вас! |
| Автор: aktuba 27.12.2006, 06:16 | ||
|
| Автор: Витаминка 27.12.2006, 07:14 |
| aktuba спасибки |
| Автор: ivan219 27.12.2006, 14:25 | ||
А что будет работать быстрее этот код или тот что выше
|
| Автор: Matematik 27.12.2006, 19:14 |
| ivan219, зависит от размера файла. Твой вариант вобщем-то "лучше", т.к. первый вариант (stringlist) загружает весь файл в память, там парсит на отдельные строки. Для небольших файлов и если не надо считать много файлов оба алгоритма "одинаковые". |
| Автор: W4FhLF 27.12.2006, 19:52 | ||
Хотите скорость?
Кол-во строк в файле размером 33 мегабайта считается абсолютно моментально, т.е. даже незаметно, что происходит. Однако, если нужно работать с большими файлами(болше 80 метров), то лучше читать файл участками по 64 Кб и считать в каждом кол-во переносов, иначе для файловых проекций, который я использовал в примере, ваш своп раздует до ужасных размеров |
| Автор: ivan219 30.12.2006, 19:31 | ||
| Да метод предложенный W4FhLF самый быстрый из 3 выше перечисленных. Я поэксперементировал так фаил в котором 100000000 строк и размером 300000000 Байт. Фаил такого типа:
получается 100000000 точек Время выполнения подщёта всего 1 Секунда Все остальные просто виснут |
| Автор: W4FhLF 31.12.2006, 07:36 |
| Ассемблер всегда нужно использоват в подобных задачах. Я думаю мой вариант не самый удачный, ибо частые кеш-промахи из-за прыжка будут постоянно перегружать конвейер процессора. |
| Автор: Girder 1.1.2007, 13:44 | ||
| Да что-ты? Ловкость рук и ни какого ассемблера("на прямую"):
PS: Да и результат более точен |
| Автор: TwisT_X 1.1.2007, 19:35 | ||
А что если вот так вот без всяких там функций?
|
| Автор: W4FhLF 1.1.2007, 20:00 | ||||
Girder,
Ну убери inc ebx в конце, я на автомате поставил, суть-то не в этом.
И что это доказывает? То, что это можно было переписать на делфи понятно. Куски кода в которых очень критична скорость, я сначала пишу на ЯВУ, дизассемблирую, смотрю как оптимизировал это компилятор, если меня что-то не удовлетворяет я переписываю этот участок кода на ассемблер и сравниваю. В данном случае компилятор проиграл. |
| Автор: Girder 1.1.2007, 21:03 |
| Да что-ты? PS: Как раз с точностью наоборот... приведенный тобой код работает медленнее по сравнению с кодом от компилятора. |
| Автор: W4FhLF 2.1.2007, 09:06 | ||
Да я ничего. Я просто открыл дизасм и посмотрел на тело цикла. А ты что? Проигрыш там незначительный, порядка 5 тактов на иттерацию, но ведь это проигрыш, а я фанат ассемблера и даже не учитывая современную архитектуру и суперскалярность процессора, где эти 5 тактов могут быть незаметны, привык выжимать из алгоритма всё. |
| Автор: W4FhLF 2.1.2007, 13:09 | ||||||
Ну только не надо говорить о рациональности по сравнению с твоим. Посмотри в дизассемблере, на одну иттерацию в твоём случае приходится два обращения к памяти и в общем случае используется 5 регистров, в моём случае обращение к памяти одно и используется 3 регистра. Поэтому в плане рациональности по сравнению с if pByte(pMemory+i)^=$0a then inc(Result); алгоритм на ассемблере удачнее. Хотя должен признать, что на практике, если не учитывать всех прочих факторов и измерить скорость с помощью GetTickCount, хотя это очень не тоно, но работают они одинаково быстро, твой алгоритм даже на 10% быстрее, но по бенчмаркам-то он проигрывает. Небольшой проигрышь в скорости в данном случае, скорее всего, объясняется тем, что оба цикла имеют размер меньший 32-64 байта, а значит могут полностью поместиться в одной линейке кеш-памяти, доступ к которой, по скорости, на порядки выше, чем доступ к оперативной памяти. Далее, ты идёшь от начала участка к концу, но как известно при запросе однойго байта из ОЗУ берётся кол-во байт равное длине линейки кеша(в зависимости от процессора 32 или 64 байта), значит следующие 32-64 иттерации процессор оперативную память не трогает. Я же иду от конца к началу, вероятнее всего процессор не может предвидеть такие ситуации и гораздо чаще обращается к ОЗУ. Что ты подразумеваешь под разрядностью команды? У команды нет такого понятия "разрядность", есть размер смещения и размер непосредственного операнда и как это "переключать разрядность команды" я тоже не понимаю. Выразись точнее. Поэтому признаю, что алгоритм мой более медленный, эх...
Обижаешь! Я думал для программистов под win32 стало уже стандартом использовать эти два служебных символа вместе.
А чего тут думать? Во-первых, если в файле кол-во строк, чья длина < 3 достаточно, то в одной иттерации можно определить сразу два(ну если без возврата каретки, то три) переноса. Во-вторых, считывается сразу машинное слово в регистр, на наших процессорах работа с DWORD'ами естественно происходит быстрее, чем с байтами и младшими частями регистров. В-третьих, сравнение происходит уже со значением регистра, а не со значением в памяти/кеше. Ну и конечно гораздо меньше кеш-промахов. За этот алгоритм твёрдая 5+ и респект |
| Автор: Girder 2.1.2007, 13:38 | ||||
см.: mov al,xx и mov ax,xxxx или mov eax,xxxxxxxx. Постоянная их смена заставляет проц также тратить время на их переключения - называеться сие чудо: Время переключение задачи команды... Т.е. постоянная чередование заставляет проц также тратить время на переключение или... если мне не изменяет память, считывание все равно происходит полное, а потом отсекаеться лишнее(но как там точно - не помню).
PS: Но енто все не главное, я просто хотел показать то что... не язык написания кода определяет его скорость |
| Автор: W4FhLF 2.1.2007, 15:29 | ||||||||
В первые слышу, чтобы изменение разрядности операндов соотносили с термином "переключение задачи" и что они как-то взаимосвязаны. Поясни подробнее, как ты это понимаешь или где ты об этом прочёл?
Может потому что в современных процессорах несколько АЛУ и распаралеливание некоторых расчётов позволяет исполнять их процессору одновременно?
Это лишь частный случай, в общем всё равно написание кода на чистом ассемблере, тем более, когда это делается с умом, даёт куда более впечатляющие результаты Да, чуть не забыл
Этот алгоритм у меня работает в 3 РАЗА быстрее самого быстрого придложенного тобою. На делфи будешь переписывать? Маски, как оказалось, рулят. |
| Автор: W4FhLF 2.1.2007, 15:51 |
| Да, забыл сказать, что алгоритм расчитан на то, что перенос это CrLf |
| Автор: Girder 2.1.2007, 15:58 |
| На счет "задачи" енто я оговорился, естественно имелось в виду "команды" Добавлено @ 16:02 Не сейчас... после 9 числа. PS: Уезжаю... |
| Автор: W4FhLF 2.1.2007, 16:05 | ||
Да наверное не получится. По-крайней мере я не не знаю и ниразу не слышал о том, что на делфи есть возможность складывать числа с учётом флага переноса(команда adc). Погуглил на тему "время переключения команды", ничё не нашёл и до этого ни в какой литературе такой характеристики у процессора не встречал, так, что не знаю о чём ты. |
| Автор: ivan219 2.1.2007, 16:41 | ||
| Вот это да к каким баталиям привёл мой оди топик Добавлено @ 16:44
Ну маленько погоричился может если подождать ещё с минуту может и былбы результат |