我如何正确使用 PChars 来改进这种优化?
我的应用程序中有一个被大量调用的函数。它基本上是一个 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;
有人“指出”:)我的方向正确吗?
I have a function that is called heavily in my app. It is basically a csv parser, which 'pops' the first value off and changes the input string to the remaining string.
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;
I want to try and optimize this routine, using PChars. So i came up with this method, but unfortunately i get weird characters in the resultant output. Im guessing its because of incorrect pointers.
//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;
Anyone "point":) me in the right direction?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
即使您让指针版本正常工作,我也不明白为什么它会更快。
调用
Pos
比循环更快,因为Pos
经过了合理优化。两个版本的分配模式是相同的,两个堆分配和一个堆释放。我会坚持使用有效的版本。您可以摆脱局部变量
s
并直接分配给Result
以跳过一些引用计数。Even if you get your pointer version to work I don't see why it would be faster.
Calling
Pos
is faster than your loop sincePos
is reasonably optimized. The allocation patterns are the same with both versions, two heap allocations and a heap deallocation. I'd stick with the version that works.You can get rid of the local variable
s
and assign direct toResult
to skip a bit of reference counting.我认为由于 ModifiedString 上的 SetString,您会得到奇怪的结果。
SetString首先设置字符串的长度,然后将缓冲区中的内容复制到新创建的字符串中。但在您的情况下,缓冲区是目的地,并且缓冲区的长度刚刚进行了调整。
只需遵循 David 的建议,不要使用 PChars。
如果你愿意,你可以让它变得更短:
I think you get strange results because of the SetString on ModifiedString.
SetString first sets the length of the string, and then copies the content from the buffer to the newly created string. But in your case the buffer is the destination, and the length of the buffer just got adjusted.
Just follow David's advise and do not use PChars.
If you want, you can make it somewhat shorter: