gpt4 book ai didi

string - 如何将 PChar 的一部分提取到字符串中?

转载 作者:行者123 更新时间:2023-12-03 15:26:44 26 4
gpt4 key购买 nike

在分析过程中,我遇到了一个需要相当多时间的函数,但本质上可以归结为这段非常简单的代码:

function GetSubstring(AInput: PChar; AStart, ASubstringLength: Integer): string;
begin
Result := Copy(AInput, AStart, ASubstringLength);
end;

此函数返回预期的子字符串,但对于较长的输入,它不能很好地扩展。我查看了 CPU View 中的汇编代码,据我所知(我通常不在汇编程序级别工作),似乎 AInput 在调用 之前隐式转换为字符串>复制

但由于此时字符串/字符数组的长度未知,因此转换代码必须遍历 PChar 的长度,直到找到 null 终止符。这可以解释较长输入的可怕缩放。

但是,由于调用者传入了 PChar 的长度,我最初认为可以将方法转换为使用 SetString 来代替。

function GetSubstring(AInput: PChar; AStart, ASubstringLength: Integer): string;
begin
SetString(Result, AInput + AStart - 1, ASubstringLength);
end;

除了 SetString 从零开始工作(不像 Copy 从一开始)之外,Copy 在验证方面似乎还有许多其他小事情它的输入,并非所有输入都被记录(例如,任何小于 1 的起始值都会更改为 1)。因此,上面的简单实现并不总是像原始实现那样工作。

我的目标是尽可能多地复制 Copy 例程,因为此函数是库的一部分,并且已被我的同事广泛使用。

我想知道以下实现是否可以实现这一点,或者我是否需要了解 Copy 的任何其他注意事项。注意:FLengthAInput 的实际长度,它来自该函数所属模块的另一部分。我在此示例中删除了其他部分。

function GetSubstring(AInput: PChar; AStart, ASubstringLength: Integer): string;
begin
if (AInput = nil) then begin
Result := '';
end else begin
if (AStart < 1) then begin
AStart := 0;
end else begin
AStart := AStart - 1;
end;
if (ASubstringLength + AStart > FLength) then begin
ASubstringLength := FLength - AStart;
end;
SetString(Result, AInput + AStart, ASubstringLength);
end;
end;

我使用的是 Delphi 2006,但我认为这在该产品的其他版本(至少是非 Unicode 版本)中没有太大不同。

最佳答案

让我们考虑一下极端情况。我认为他们是:

  1. AInput无效。
  2. AStart < 1 .
  3. AStart > FLength .
  4. ASubstringLength < 0 .
  5. ASubstringLength + (AStart-1) > FLength .

我认为我们可以忽略情况 1。调用者有责任提供有效的 PChar 。事实上你检查了 AInput <> nil在我看来已经迈得太远了,因为 nil不是有效的 PChar .

其余的您已经涵盖了 2 和 5,但没有涵盖 3 和 4。因此,如果用户提供值 AStart太大了,那么您将读取字符串的末尾。同样,用户可以轻松提供否定的 ASubstringLength 。我认为您不需要任何人编写代码来检查这些情况,因为您显然非常有能力。

现在,如果您真的关心性能的每一点下降,那么您不应该检查任何这些情况。要求用户传递有效参数。在 Debug模式下,使用 {$IFOPF D+}Assert你可以检查输入。当然,如果这些论点来自外部来源,那么它们应该得到验证。

另一方面,原始代码遭受的最大性能损失是对整个字符串的不必要扫描,以及复制到中间堆分配的字符串。一旦您删除了这些内容(就像您所做的那样),进一步提高性能的机会就会大大减少。

关于string - 如何将 PChar 的一部分提取到字符串中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30831477/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com