我的应用程序中有一个被大量调用的函数。它基本上是一个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;
任何人“指出”:)我朝着正确的方向前进?
答案 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;