Inline директива нетипично замедляет функцию

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

alexrayne
постоялец
Сообщения: 125
Зарегистрирован: 03.12.2008 15:56:26

Сообщение alexrayne »

вообчето вызов локальной маленькой функции на х86 обходится почти бесплатно. зато памяти он кушает меньше гораздо че ваш прямой ori_Hash32.BKDRHash(key) and $7FFFFFFF;. тобиш тут вы можете сильно облегчить компилятору жизнь - ему ведь приходится делать нелегкий выбор между компактным кодом и теоретически быстрым. на платформах АРМ и РРС ситуация иная и надо спрашивать специалистов. оптимизация инлайн - весьма неоднозначна (и в ГСС тоже), если специалист с трудом скажет вам выиграете или потеряете, что Вы ждете от компилятора?

реальный тормоз в вашей проге использование АнсиСтрок - вам уже выше несколько раз об етом сказали. советую таки написать хешфункцию работающую на PChar и передавать ей @SomeAnsiStringVar[1]
devels
постоялец
Сообщения: 137
Зарегистрирован: 01.09.2010 12:14:38

Сообщение devels »

PAnsiChar оказался еще более тормозом, по крайней мере в делфи, вызов функции даже с const в 2,5 раза медленнее чем обычного string, а с учетом того, что любой PAnsiChar надо перебирать путем inc(), то модификатор const нельзя использовать.

Так что, пока остановлюсь на AnsiString, все таки родные строковые типы работают быстрее, по крайней мере вызов функций с параметрами строк.
Max Rusov
постоялец
Сообщения: 191
Зарегистрирован: 25.04.2009 15:46:03

Сообщение Max Rusov »

devels писал(а):PAnsiChar оказался еще более тормозом

Просто Вы не умеете их готовить. Код в студию.
Аватара пользователя
Иван Шихалев
энтузиаст
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург
Контактная информация:

Сообщение Иван Шихалев »

devels писал(а): любой PAnsiChar надо перебирать путем inc()


Зачем? Адресация через [] чем не устраивает?
devels
постоялец
Сообщения: 137
Зарегистрирован: 01.09.2010 12:14:38

Сообщение devels »

Ну вот, без inc, все равно медленно, либо идти до #0 символа, либо узнавать длину через StrLen (либо хранить длину где-то в другой переменной заранее).

Код: Выделить всё

function HashTable_Func3(const key: PAnsiChar): Cardinal;
const Seed = 31; (* 31 131 1313 13131 131313 etc... *)
var
  i: Integer;
begin
  Result := 0;
  i := 0;
  while Key[i] <> #0 do
  begin
    Result := (Result * Seed) + Ord(Key[i]);
    inc(i);
  end;

  Result := Result and $7FFFFFFF;
end;


1300 mlsec, AnsiString - 700 mlsec (причем у AnsiString внутри еще вызывается функция length)

Если передавать в HashTable_Func3 еще и длину строки, то скорость сравняется, тоже будет 700 mlsec, ну и что быстрее? Что я делаю не так?
Max Rusov
постоялец
Сообщения: 191
Зарегистрирован: 25.04.2009 15:46:03

Сообщение Max Rusov »

devels писал(а):Что я делаю не так?

Для начала - Вы не приводите полный код примера.
Павел Ишенин
постоялец
Сообщения: 475
Зарегистрирован: 24.03.2007 09:16:52

Сообщение Павел Ишенин »

А если попробовать так?

Код: Выделить всё

function HashTable_Func3(key: PAnsiChar): Cardinal;
const Seed = 31; (* 31 131 1313 13131 131313 etc... *)
begin
  Result := 0;
  while Key^ <> #0 do
  begin
    Result := (Result * Seed) + byte(key^);
    inc(key);
  end;

  Result := Result and $7FFFFFFF;
end;
alexrayne
постоялец
Сообщения: 125
Зарегистрирован: 03.12.2008 15:56:26

Сообщение alexrayne »

чето Вы действительно темните. AnsiString - ето указатель на структуру которая содержит длину строки и PAnsiChar к самой строке. ну и какая разница как ето передавать? если Вы передадите ето параметрами то по крайней мере обойдетесь без подсчета ссылок. итоговый код хеша в обоих вариантах не должен измениться значительно.
Вам в хеше действительно нужна длина строки до ее полного просмотра? если строка в процессе калькуляции сканируется вся, то уж и длину можно на лету посчитать.
Вобчем, имхо, комайте глубже, бейте копытом, ройте носом...

Добавлено спустя 12 минут 34 секунды:
Павел Ишенин писал(а):А если попробовать так?

Код: Выделить всё

function HashTable_Func3(key: PAnsiChar): Cardinal;
const Seed = 31; (* 31 131 1313 13131 131313 etc... *)
begin
  Result := 0;
  while Key^ <> #0 do
  begin
    Result := (Result * Seed) + byte(key^);
    inc(key);
  end;

  Result := Result and $7FFFFFFF;
end;


если хочется сохранить const, введите локальную переменную темп и скопируйте в нее параметр...
Max Rusov
постоялец
Сообщения: 191
Зарегистрирован: 25.04.2009 15:46:03

Сообщение Max Rusov »

const для PChar не имеет никакого практического смысла.
alexrayne
постоялец
Сообщения: 125
Зарегистрирован: 03.12.2008 15:56:26

Сообщение alexrayne »

Max Rusov писал(а):const для PChar не имеет никакого практического смысла.

практического неимеет, зато намекает что строка параметра не модифицируется....
Max Rusov
постоялец
Сообщения: 191
Зарегистрирован: 25.04.2009 15:46:03

Сообщение Max Rusov »

Любой фактический параметр, передаваемый по значению не может модифицироваться. А что там происходит внутри функции с формальным параметром - как бы никого не должно волновать.

Добавлено спустя 9 часов 33 минуты 41 секунду:
Upd.

И, кстати, ничего насчет подобного насчет "строки" он не гарантирует. Строка то, как раз, может модифицироваться сколько угодно.
Ответить