소스 검색

* patch by Rika: optimize Pos(), resolves #40088

florian 2 년 전
부모
커밋
84e7a17b67
2개의 변경된 파일60개의 추가작업 그리고 90개의 파일을 삭제
  1. 32 44
      rtl/inc/astrings.inc
  2. 28 46
      rtl/inc/ustrings.inc

+ 32 - 44
rtl/inc/astrings.inc

@@ -948,27 +948,24 @@ end;
 {$ifndef FPC_HAS_POS_SHORTSTR_ANSISTR}
 {$define FPC_HAS_POS_SHORTSTR_ANSISTR}
 Function Pos(Const Substr : ShortString; Const Source : RawByteString; Offset : Sizeint = 1) : SizeInt;
-
 var
-  i,MaxLen : SizeInt;
-  pc : PAnsiChar;
+  i,MaxLen,nsource,nsub,d : SizeInt;
 begin
   Pos:=0;
-  if (Length(SubStr)>0) and (Offset>0) and (Offset<=Length(Source)) then
+  nsource:=Length(Source);
+  nsub:=Length(Substr);
+  if (nsub>0) and (Offset>0) and (Offset<=nsource) then
    begin
-     MaxLen:=Length(source)-Length(SubStr);
-     i:=Offset-1;
-     pc:=@source[Offset];
+     MaxLen:=nsource-nsub+1;
+     i:=Offset;
      while (i<=MaxLen) do
       begin
-        inc(i);
-        if (SubStr[1]=pc^) and
-           (CompareByte(Substr[1],pc^,Length(SubStr))=0) then
-         begin
-           Pos:=i;
-           exit;
-         end;
-        inc(pc);
+        d:=IndexByte(Source[i],MaxLen-i+1,byte(Substr[1]));
+        if d<0 then
+          exit;
+        if CompareByte(Substr[1],Source[i+d],nsub)=0 then
+          exit(i+d);
+        i:=i+d+1;
       end;
    end;
 end;
@@ -979,25 +976,23 @@ end;
 {$define FPC_HAS_POS_ANSISTR_ANSISTR}
 Function Pos(Const Substr : RawByteString; Const Source : RawByteString; Offset : Sizeint = 1) : SizeInt;
 var
-  i,MaxLen : SizeInt;
-  pc : PAnsiChar;
+  i,MaxLen,nsource,nsub,d : SizeInt;
 begin
   Pos:=0;
-  if (Length(SubStr)>0) and (Offset>0) and (Offset<=Length(Source)) then
+  nsource:=Length(Source);
+  nsub:=Length(Substr);
+  if (nsub>0) and (Offset>0) and (Offset<=nsource) then
    begin
-     MaxLen:=Length(source)-Length(SubStr);
-     i:=Offset-1;
-     pc:=@source[Offset];
+     MaxLen:=nsource-nsub+1;
+     i:=Offset;
      while (i<=MaxLen) do
       begin
-        inc(i);
-        if (SubStr[1]=pc^) and
-           (CompareByte(Substr[1],pc^,Length(SubStr))=0) then
-         begin
-           Pos:=i;
-           exit;
-         end;
-        inc(pc);
+        d:=IndexByte(Source[i],MaxLen-i+1,byte(Substr[1]));
+        if d<0 then
+          exit;
+        if CompareByte(Substr[1],Source[i+d],nsub)=0 then
+          exit(i+d);
+        i:=i+d+1;
       end;
    end;
 end;
@@ -1012,23 +1007,16 @@ end;
 { (exact match for first argument), also with $h+ (JM)           }
 Function Pos(c : AnsiChar; Const s : RawByteString; Offset : Sizeint = 1) : SizeInt;
 var
-  i: SizeInt;
-  pc : PAnsiChar;
+  ns,idx: SizeInt;
 begin
-  Pos:=0;
-  If (Offset<1) or (Offset>Length(S)) then 
-    exit;
-  pc:=@s[OffSet];
-  for i:=Offset to length(s) do
-   begin
-     if pc^=c then
-      begin
-        pos:=i;
-        exit;
-      end;
-     inc(pc);
-   end;
   pos:=0;
+  ns:=length(s);
+  if (Offset>0) and (Offset<=ns) then
+  begin
+    idx:=IndexByte(s[Offset],ns-Offset+1,byte(c));
+    if idx>=0 then
+      pos:=Offset+idx;
+  end;
 end;
 {$endif FPC_HAS_POS_ANSICHAR_ANSISTR}
 

+ 28 - 46
rtl/inc/ustrings.inc

@@ -1187,25 +1187,23 @@ end;
 {$define FPC_HAS_POS_UNICODESTR_UNICODESTR}
 Function Pos (Const Substr : UnicodeString; Const Source : UnicodeString; Offset: Sizeint = 1) : SizeInt;
 var
-  i,MaxLen : SizeInt;
-  pc : punicodechar;
+  i,MaxLen,nsource,nsub,d : SizeInt;
 begin
   Pos:=0;
-  if (Length(SubStr)>0) and (Offset>0) and (Offset<=Length(Source)) then
+  nsource:=Length(Source);
+  nsub:=Length(Substr);
+  if (nsub>0) and (Offset>0) and (Offset<=nsource) then
    begin
-     MaxLen:=Length(source)-Length(SubStr)-(OffSet-1);
-     i:=0;
-     pc:=@source[OffSet];
+     MaxLen:=nsource-nsub+1;
+     i:=Offset;
      while (i<=MaxLen) do
       begin
-        inc(i);
-        if (SubStr[1]=pc^) and
-           (CompareWord(Substr[1],pc^,Length(SubStr))=0) then
-         begin
-           Pos:=Offset+i-1;
-           exit;
-         end;
-        inc(pc);
+        d:=IndexWord(Source[i],MaxLen-i+1,word(Substr[1]));
+        if d<0 then
+          exit;
+        if CompareWord(Substr[1],Source[i+d],nsub)=0 then
+          exit(i+d);
+        i:=i+d+1;
       end;
    end;
 end;
@@ -1217,23 +1215,16 @@ end;
 { Faster version for a unicodechar alone }
 Function Pos (c : UnicodeChar; Const s : UnicodeString; Offset: Sizeint = 1) : SizeInt;
 var
-  i: SizeInt;
-  pc : punicodechar;
+  ns,idx: SizeInt;
 begin
-  if (Offset>0) and (Offset<=length(s)) then
-   begin
-     pc:=@s[OffSet];
-     for i:=OffSet to length(s) do
-       begin
-         if pc^=c then
-           begin
-             pos:=i;
-             exit;
-           end;
-         inc(pc);
-       end;
-   end;
   pos:=0;
+  ns:=length(s);
+  if (Offset>0) and (Offset<=ns) then
+  begin
+    idx:=IndexWord(s[Offset],ns-Offset+1,word(c));
+    if idx>=0 then
+      pos:=Offset+idx;
+  end;
 end;
 {$endif FPC_HAS_POS_UNICODECHAR_UNICODESTR}
 
@@ -1274,25 +1265,16 @@ end;
 { (exact match for first argument), also with $h+ (JM)           }
 Function Pos (c : Char; Const s : UnicodeString; Offset: Sizeint = 1) : SizeInt;
 var
-  i: SizeInt;
-  wc : unicodechar;
-  pc : punicodechar;
+  ns,idx: SizeInt;
 begin
-  if (Offset>0) and (Offset<=Length(S)) then
-    begin
-      wc:=c;
-      pc:=@s[OffSet];
-      for i:=OffSet to length(s) do
-       begin
-         if pc^=wc then
-          begin
-            pos:=i;
-            exit;
-          end;
-         inc(pc);
-       end;
-    end;
   pos:=0;
+  ns:=length(s);
+  if (Offset>0) and (Offset<=ns) then
+  begin
+    idx:=IndexWord(s[Offset],ns-Offset+1,word(unicodechar(c)));
+    if idx>=0 then
+      pos:=Offset+idx;
+  end;
 end;
 {$endif FPC_HAS_POS_CHAR_UNICODESTR}