如何正确使用PChars来改善这种优化?

时间:2011-04-19 08:23:04

标签: string delphi pchar

我的应用程序中有一个被大量调用的函数。它基本上是一个csv解析器,它“弹出”第一个值并将输入字符串更改为剩余的字符串。

function StripString(mask: string; var modifiedstring: string): string;
var
  index,len: integer;
  s: string;
begin
    Index := pos(Mask, ModifiedString);
    len := Length(ModifiedString);
    if index <> 0 then
    begin
        if Index <> 1 then
        begin
            s := LeftStr(ModifiedString, index - 1);
            ModifiedString := RightStr(ModifiedString, len-index);
        end else begin
            if Length(ModifiedString)>1 then
              ModifiedString := Copy(ModifiedString,2,len)
            else
              ModifiedString := '';
            s := '';
        end;
    end else begin
        s := ModifiedString;
        ModifiedString := '';
    end;
    result := s
end;

我想尝试使用PChars优化此例程。所以我想出了这个方法,但遗憾的是我在结果输出中得到了奇怪的字符。我猜它是因为指针不正确。

//faster method - uses PChars
function StripStringEx(mask: char; var modifiedstring: string): string;
var
  pSt,pCur,pEnd : Pchar;
begin
    pEnd := @modifiedString[Length(modifiedString)];
    pSt := @modifiedString[1];
    pCur := pSt;
    while pCur <= pEnd do
    begin
         if pCur^ = mask then break;
         inc(pCur);
    end;
    SetString(Result,pSt,pCur-pSt);
    SetString(ModifiedString,pCur+1,pEnd-pCur);
end;

任何人“指出”:)我朝着正确的方向前进?

2 个答案:

答案 0 :(得分:3)

即使你的指针版本工作,我也不明白它为什么会更快。

调用Pos比您的循环更快,因为Pos已合理优化。两个版本的分配模式相同,两个堆分配和堆释放。我坚持使用有效的版本。

您可以删除局部变量s并直接指定给Result以跳过一些引用计数。

答案 1 :(得分:1)

我认为你会因为ModifiedString上的SetString而得到奇怪的结果。 SetString首先设置字符串的长度,然后将内容从缓冲区复制到新创建的字符串。但在你的情况下,缓冲区是目的地,缓冲区的长度刚刚调整。

请遵循David的建议,不要使用PChars。

如果你愿意,你可以缩短一点:

function StripString(const Mask: string; var ModifiedString: string): string;
var
  Index: Integer;
begin
  Index := Pos(Mask, ModifiedString);
  if Index <> 0 then
  begin
    Result := LeftStr(ModifiedString, Index - 1);
    Delete(ModifiedString, Index);
  end
  else
  begin
    Result := ModifiedString;
    ModifiedString := '';  
  end;
end;