Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
11 / 11 / 3
Регистрация: 02.08.2012
Сообщений: 128
1

Самописный PosEx vs StrUtils PosEx

10.08.2013, 23:21. Показов 2104. Ответов 1
Метки нет (Все метки)

Подскажите пожалуйста, кто разбирается, почему самописный PosEx работает в два! раза медленней, чем StrUtils'овый из Embarcadero RAD Studio XE2.

Самописный:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int PosEx(const String subString, const String str, int offset)
{
    if (subString == "" || str == "" || offset < 1)
        return 0;
    if (offset == 1)
        return Pos(subString,str);
    int subStringLength = subString.Length();
    int segmentStringLength = str.Length() - subStringLength+1;
    for (; offset <= segmentStringLength; offset++)
        if (str[offset] == subString[1]) {
            int i = 1;
            for (; i < subStringLength && str[offset + i] == subString[1+i]; i++) {}
            if (i == subStringLength)
                return offset;
        }
    return 0;
}
Из файла System.StrUtils.pas (там внизу еще ассемблерский код, не стал копировать...можете сами глянуть, у кого стоит RAD):
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
function PosEx(const SubStr, S: string; Offset: Integer): Integer;
{$IFDEF PUREPASCAL}
var
  I, LIterCnt, L, J: Integer;
  PSubStr, PS: PChar;
begin
  if SubStr = '' then
    Exit(0);
 
  { Calculate the number of possible iterations. Not valid if Offset < 1. }
  LIterCnt := Length(S) - Offset - Length(SubStr) + 1;
 
  { Only continue if the number of iterations is positive or zero (there is space to check) }
  if (Offset > 0) and (LIterCnt >= 0) then
  begin
    L := Length(SubStr);
    PSubStr := PChar(SubStr);
    PS := PChar(S);
    Inc(PS, Offset - 1);
 
    for I := 0 to LIterCnt do
    begin
      J := 0;
      while (J >= 0) and (J < L) do
      begin
        if (PS + I + J)^ = (PSubStr + J)^ then
          Inc(J)
        else
          J := -1;
      end;
      if J >= L then
        Exit(I + Offset);
    end;
  end;
 
  Result := 0;
end;
{$ELSE !PUREPASCAL}
Кастомизированный StrUtils'овый PosEx (из Delphi в C++):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int PosEx(const String subString, const String str, int offset)
{
  if (subString == "")
    return 0;
  // Calculate the number of possible iterations. Not valid if Offset < 1.
  int LIterCnt = str.Length() - offset - subString.Length()+1;
  // Only continue if the number of iterations is positive or zero (there is space to check)
  if (offset > 0 && LIterCnt >= 0)
  {
    int L = subString.Length();
    /// PChar PSubStr = PChar(SubStr);
    /// PChar PS = PChar(S);
    /// Inc(PS, Offset - 1);
    for (int I = 0; I <= LIterCnt; I++) {
      int J = 0;
      while (J >= 0 && J < L) {
        /// if (PS + I + J)^ = (PSubStr + J)^ then
        if (str[offset-1 + I + J] == subString[1+J])
          J++;
        else
          J = -1;
      }
      if (J >= L)
        return I + offset;
    }
  }
  return 0;
}
Так вот:
При подключении StrUtils и вызова PosEx - он выполняется в 2 раза быстрее, чем если я вызову свой PosEx или переписанный PosEx с делфи. Переписанный и свой PosEx работают с одинаковой скорость...

Помимо догадки, что при вызове PosEx из StrUtils выполняется ассемблеровский код и поэтому он работает быстрее, у меня решений нет. Может кто другой знает причину?
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.08.2013, 23:21
Ответы с готовыми решениями:

Работа с posEx
Доброго времени суток, программисты! Сколько дней ломаю голову и читаю, но не могу реализовать...

Ругается на PosEx
Ругается на PosEx. причем непонятно, этот код взял из базы кода. Успешно работает в других...

Поиск в Memo posEx
Здравствуйте всем! Помогите пожалуйста разобраться есть два мемо хочу автоматом из одного...

Переработка функции PosEx
Здравствуйте! Есть функция PosEx, которая ищет текст сверху вниз, как ее переделать, что бы она...

1
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
31187 / 20385 / 7940
Регистрация: 22.10.2011
Сообщений: 35,345
Записей в блоге: 6
11.08.2013, 01:06 2
Цитата Сообщение от ExeiLj Посмотреть сообщение
Помимо догадки, что при вызове PosEx из StrUtils выполняется ассемблеровский код и поэтому он работает быстрее
Правильная догадка. Потому что в самом начале файла System.StrUtils.pas написано:
Delphi
1
2
3
4
5
{$IFDEF CPUX86}
  {$DEFINE X86ASM}
{$ELSE !CPUX86}
  {$DEFINE PUREPASCAL}
{$ENDIF !CPUX86}
, то есть, PUREPASCAL определяется только тогда, когда не определено CPUX86. Это случается только при использовании DCC64 и DCCIOSARM: Predefined Conditionals. В случае использования 32-битного компилятора под Windows (а с XE2 у тебя еще есть только 32-бита) будет работать именно ассемблерный код.
2
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.08.2013, 01:06

PosEx Парадокс какой-то
Вот имеется проц-ра; procedure TForm1.SecondAlgor(var S:String); var i:Integer; begin for i:=1...

Как найти процедуру PosEx?
Доброго времени суток. У меня в модуле StrUtils нет процедуры PosEx. Может этот модуль можно где...

Delphi не понимает функцию PosEx
кто знает почему это, какие причины могут быть?

Pos,PosEx поиск подстроки в строке
Почему не ищет дальше в строке подходящие слова? есть текст: лол лол лол лол лол лол лооол...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.