Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Оптимизация кода, работающего с типом string 
V
    Опции темы
Coder
Дата 12.5.2008, 10:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 5
Всего: 11



В программе есть простенькая функция:
Код

function GetOneLine : string;
var
  u1, u2 : integer;
begin
  u1:=pos('>',RetData);
  if u1=0 then
    begin
      Result:='';
      exit;
    end;

  u2:=pos('<',RetData);
  if u2=0 then
    begin
      Result:='';
      exit;
    end;

  result:=copy(RetData,u1+1,u2-u1-1);
  delete(RetData,u1,u2-u1+1);
end;

Ее назначение из всего входящего пакета выделять сообщения, возвращать их для дальнейшей обработки и освобождать пакет от них.
Формат пакета такой:
>data0<>data1<>data2<>data3<>data4<.....

Собственно формат входящего пакета зависит не от меня. Выделение сообщений я делаю самым очевидным образом - функциями для работы со строками.
Вопрос: Как можно ускорить выполнение данной функции? Она у меня может вызываться до несколько десятков тысяч раз, что ведет к хорошему замедлению программы!


Это сообщение отредактировал(а) Coder - 12.5.2008, 10:18
PM MAIL   Вверх
Beltar
Дата 12.5.2008, 23:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 3
Всего: 7



Можно перебирать в один проход, используя 2 while, тогда на вызове Pos можно сэкономить. Найти первый знак, начать копировать, найти второй знак, перестать копировать. Если вероятность копирования очень велика, цена промахов может оказаться незначительной. Строку RetData, возможно, лучше в PChar, все равно ведь массив байтов принимаешь, и ходить по ней прибавляя единичку к указателю, это думаю быстрее будет, чем RetData[i]. Только если потом надо будет ее в String переводить, это не знаю.



--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
aktuba
Дата 12.5.2008, 23:54 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 16
Всего: 38



А еще проще, в данном случае, получить сразу все данные одной регуляркой.


--------------------
user posted image
PM MAIL WWW Skype   Вверх
dumb
Дата 13.5.2008, 00:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


sceloglauxalbifacies
****


Профиль
Группа: Экс. модератор
Сообщений: 2929
Регистрация: 16.6.2006

Репутация: 13
Всего: 158



regexp в данном случае совершенно не оправдан и будет оттормаживать.

Coder, надо не функцию править, а пересматривать код работы с этой строкой вообще. главный тормоз в функции - delete. если от него избавишься, 99% тормозов уберешь.
PM MAIL   Вверх
Coder
Дата 13.5.2008, 06:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 5
Всего: 11



dumb, действительно, я в этом убедился  сделав профилирование этих функций.

38428 сообщений в RetData:
pos - 0 ms
copy - 31 ms
delete - 28964 ms (!!)

61322 сообщений в RetData:
pos - 62 ms
copy - 93 ms
delete - 99783 ms (!!)

Спасибо за наводку! smile

PM MAIL   Вверх
TName
Дата 14.5.2008, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 16.3.2008

Репутация: нет
Всего: нет



я в задачу сильно что-то не вник... может сразу в СтрингЛист весь пакет, а потом его отрабатывать?
И ещё модуль есть вот такой, говорят шустрее работает, чем стандартные функции.


Присоединённый файл ( Кол-во скачиваний: 12 )
Присоединённый файл  QStrings.pas 661,30 Kb
PM MAIL   Вверх
aktuba
Дата 14.5.2008, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 16
Всего: 38



Цитата(dumb @  13.5.2008,  01:22 Найти цитируемый пост)
regexp в данном случае совершенно не оправдан и будет оттормаживать.

вряд-ли... насколько я помню, там не используется Delete, только Copy вроде.

Добавлено через 43 секунды
Coder, попробуй переписать, используя Pos..PosEx


--------------------
user posted image
PM MAIL WWW Skype   Вверх
Coder
Дата 15.5.2008, 01:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 5
Всего: 11



TName, спасибо, попробую.


aktuba, я тоже склоняюсь к мысли Pos -> PosEx -> Copy. Еще не сделал, потому что требует модернизации других участков программы, работающих с RetData.
А с RegExp я не работал и разбираться сейчас нет времени. Поэтому сначала нужно будет как-то убедиться в эффективности, прежде чем браться за изучение и применение.

Это сообщение отредактировал(а) Coder - 15.5.2008, 01:16
PM MAIL   Вверх
Coder
Дата 15.5.2008, 03:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 5
Всего: 11



Протестировал функцию Q_Delete из модуля QStrings.pas. Вот результаты.

Тест с функцией Q_Delete()

61322 сообщений в RetData:
pos=45 ms
copy=202 ms
q_delete=124154 ms

Повторный вызов с теми же данными в RetData:
pos=15 ms
copy=126 ms
q_delete=122485 ms 

Тест с функцией delete()

61322 сообщений в RetData:
pos=15 ms
copy=31 ms
delete=94841 ms

Повторный вызов с теми же данными в RetData:
pos=0 ms
copy=31 ms
delete=100233 ms


Как видно, delete все же работает быстрее! Интересно, что разработчики QStrings пишут - "Эта функция работает быстрее, чем стандартная Delete." Откуда такие выводы?

Время засекал так:
Код

function GetOneLine : string;
var
  u1, u2 : integer;
  t1, t2 : cardinal;
begin
t1:=GetTickCount;
  u1:=pos('>',RetData);
  if u1=0 then
    begin
      Result:='';
      exit;
    end;

  u2:=pos('<',RetData);
  if u2=0 then
    begin
      Result:='';
      exit;
    end;
t2:=GetTickCount;
_pos_time:=_pos_time+(t2-t1); // время работы двух pos()+проверки

t1:=GetTickCount;
  result:=copy(RetData,u1+1,u2-u1-1);
t2:=GetTickCount;
_copy_time:=_copy_time+(t2-t1);

t1:=GetTickCount;
  delete(RetData,u1,u2-u1+1);
//  Q_Delete(RetData,u1,u2-u1+1);
t2:=GetTickCount;
_del_time:=_del_time+(t2-t1);
end;



PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0468 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.