![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Хоббит |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1263 Регистрация: 6.11.2005 Репутация: нет Всего: 1 |
Есть строка, представляющая алгебраическое выражение. Строка очень большая, в перспективе до сотен мегабайт (возможно это уже не строка а файл на диске, в котором есть выражении и их него происходит считывание данных). Необходимо одно подвыражение в строке разбить и заменить другим.
К примеру 3 + fn(a1, l, c1) + 4 * fn(a1, l, c2) - 5 * fn(a3, l, c3) Заменить на 3 + f1a1 + 4 * f2a1 - 5 * f3a3 Использовал для строки класс string, а для поиска и операций find, replace, substr. Профайлер показывает, что на эту замену уходит до 60% времени программы. Хотелось бы оптимизировать операции. Я так понимаю придется работать с char* (C строки). Как самым быстрым образом, выполнять поиск в С строках, извлекать подстроку и соединять строки. Так же, как бы вы предложили выделять память под новые строки. Пока все это так
|
|||
|
||||
vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
кто тебе сказал, что с ними будет быстрее работать? |
|||
|
||||
Хоббит |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1263 Регистрация: 6.11.2005 Репутация: нет Всего: 1 |
Я предположил. К примеру при конкатенации строк, каждый раз вычисляется длина строки, эта операции чуть ли не самая долгая из всех. Работаю с char* я смогу хранить указатель на конец строки и организовать свой метод конкатенации строк. Подействует?
|
|||
|
||||
vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
скорее всего length() \представляет собой end-begin, так что все работает быстро. Я лично не проверял, но не вижу почему std::string может работать медленее. Поимщи, на форуме было сравнение скорости работы, и если мне память не изменяет работа со string получалась быстрее. |
|||
|
||||
Kallikanzarid |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 240 Регистрация: 9.11.2008 Репутация: нет Всего: 3 |
Делать замену в строке такого размера - самоубийство. Лучше сразу пиши в файл вывода то, что нужно.
|
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 12 Всего: 459 |
Операции replace, substr и конкатинация действительно медленные. Было дело, что мне удалось увеличить скорость не менее чем в 4 раза заменив wstring на TCHAR* , но дело было не просто в замене, а в том что при помощи TCHAR* удобно делать низкоуровневые оптимизации. Кроме того можно выиграть если все выделения памяти внутри цикла производить не в куче, а в специальном пуле (как в стеке), т.е. память освободиться только по выходу из цикла целиком.
Бить нужно в выделения памяти. Оператор "+" это выделение памяти с копированием, replace это выделение памяти с еще большим копированием, substr выделение памяти с небольшим копированием. Компиляторы С++ чаще всего имеют фиговенькие менеджеры куч, потому операция выделения памяти весьма не быстрая. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
Попробуйте пользовать два массива/строки исходный и целевой. В целевом заранее зарезервировать память нужного размера, и организовать туда выборочное копирование по Вашему заданию. |
|||
|
||||
Lycifer |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 144 Регистрация: 4.11.2007 Репутация: нет Всего: нет |
Если говорить об оптимизации то явно STL не оптимизирована.
Оптимизация работы с памятью это сложный вопрос(как правило включается зависимость железа) - разворот циклов на чтение.запись памяти - Как читается указатель Вообщем очень много , советую почитать литературу. |
|||
|
||||
Хоббит |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1263 Регистрация: 6.11.2005 Репутация: нет Всего: 1 |
Понравился совет mes. В принципе сам пришел к такому же решению. Попробую, скажу результат.
Если в дальнейшем не будет хватать памяти, организую это все через файлы и потоки. |
|||
|
||||
Хоббит |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1263 Регистрация: 6.11.2005 Репутация: нет Всего: 1 |
Второй вариант.
Выигрыша во времени НЕТ! Мои надежды не оправдались. Добавлено через 29 секунд Видно нужны другие подходы. |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
...
Это сообщение отредактировал(а) mes - 18.1.2009, 18:15 |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Для такой задачи нужно кардинально другой метод обработки - нужно не перепахивать многократно всю строку для каждой fn, а делать все замены на одном проходе (можно даже на лету, не сохраняя собственно строку). Ищи по ключевым словам regex, NFA, DFA
|
|||
|
||||
kolobok0 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 64 Регистрация: 24.12.2008 Репутация: нет Всего: 2 |
во втором варианте вы делаете проход побайтно!!! ![]() естественней будет медленней. и странно что то же самое получили ![]() постарайтесь использовать приведённые тут советы..и помните.. 1) функции из библиотек обрабатываемые скопом инфу - оптимизированные на низком уровне...наверняка поиск символа в строке будет в коде звучать типа substr т.е. быстрее вряд ли придумаешь... 2) постарайтесь измерять и проанализировать где ЯВНО у вас встречаються тормоза...и можно ли эти участки сделать паралельно. Т.е. например поиск подстрок выражений - скопом, а вот обработку их отдельно - в потоках. грамотная ось будет давать выигрыш в скорости даже на одном проце с одним конвеером(к сожалению форточки к этим осям не относяться) ... 3) постарайтесь глобально проанализировать задачу...возможно решение в лоб (поиск и замена) - не есть оптимум к результату... может имеет смысл искать начало и конец этих функций на момент создания(вставки) , информацию сохранять и потом именно её и кушать на входе? удачи Вам (круглый) |
|||
|
||||
kshyms |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 303 Регистрация: 30.8.2006 Где: Душанбе Репутация: нет Всего: 0 |
|
|||
|
||||
GoldFinch |
|
|||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 15 Всего: 26 |
если говорить о хорошей оптимизации, то вместо того чтобы искать "хорошую" стандартную функцию для общих задач, лучше грамотно поставить задачу и сделать свою функцию под эту частную задачу.
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |