【发布时间】:2011-09-18 16:02:42
【问题描述】:
在从磁盘读取数据(数据意味着排他字符串)的函数中,我应该更喜欢哪个?哪个更好?
A) DiskStream.Read(Pointer(s)^, Count)
or
B) DiskStream.Read(s[1], Count)
注意:
我知道两者的结果相同。
我知道在调用 Read 之前我必须设置 S 的长度。
更新
S 是 AnsiString。
这是完整的功能:
{ 从文件中读取一堆字符。为什么是“ReadChars”而不是“ReadString”?此函数读取 C++ 字符串(字符串的长度也未写入磁盘)。所以,我必须给出要读取的字符数作为参数。 }
function TMyStream.ReadChars(out s: AnsiString; CONST Count: Longint): Boolean;
begin
SetLength(s, Count);
Result:= Read(s[1], Count)= Count;
end;
速度测试
在我的速度测试中,第一种方法比第二种方法快一点。我使用了一个 400MB 的文件,从中读取了大约 200000 次字符串。该进程被设置为高优先级。
有史以来最好的阅读时间是:
变体 B 为 1.35,变体 A 为 1.37。
平均:
平均而言,B 的得分也比 A 高 20 毫秒。
对每个变体重复测试 15 次。
差别真的很小。它可能落入测量误差范围内。 如果我更频繁地从更大的文件中读取字符串,这可能会很重要。 但目前让我们假设两行代码的性能相同。
回答
变体 A - 可能会稍微快一点
变体 B - (显然)更容易阅读,并且更接近德尔福。我的首选。
注意:
我在 TStreamReadBuffer 示例中看到 Embarcadero 使用变体 A,但使用的是 TBytes 而不是 String。
【问题讨论】:
-
这是哪个Delphi版本?由于 Unicode 更改,您可能会在 D2009+ 中使用这种方法遇到问题。 Nick Hodges 的这篇文章阐明了在较新的 Delphi 版本中应该如何做:edn.embarcadero.com/article/38693
-
嗨,詹斯。我忘记了。我更新了我的问题以表明 s 是 AnsiString。
-
刚刚看到您更新的速度测试。我想说 20 毫秒是值得为更好的代码可读性和避免因不调用
UniqueString而可能出现的任何问题付出的代价,不是吗? -
当这些问题陷入对可疑优化的神秘讨论时,我讨厌它。为什么我们似乎对性能比对正确性更感兴趣?显然两者都很重要,但我真的强烈认为正确性必须放在首位。
-
@Altar:你说如果你从一个更大的文件中读取更多的字符串,差异会更大。这点考虑一下吧。您正在阅读一个 400 MB 的文件。将所有内容乘以 10,4 GB 文件的差异为 0.2 秒。您现在遇到了 32 位地址空间的限制,而您仍然只节省了微不足道的几分之一秒。真的不值得。
标签: delphi