0

我有一个在我的应用程序中被大量调用的函数。它基本上是一个 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;

任何人都“指向”:) 我的方向正确吗?

4

2 回答 2

3

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

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

您可以摆脱局部变量s并直接分配给以Result跳过一些引用计数。

于 2011-04-19T08:31:33.027 回答
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;
于 2011-04-19T18:53:25.243 回答