指针^与s [1] [英] Pointer(s)^ versus s[1]

查看:126
本文介绍了指针^与s [1]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在从磁盘读取数据(数据表示唯一字符串)的函数中,我应该选择哪个?哪个更好?

In a function that reads data (data meaning exclusively strings) from disk, which should I prefer? Which is better?

A) DiskStream.Read(Pointer(s)^, Count)
or
B) DiskStream.Read(s[1], Count)

注意:

我知道两者的结果相同。

我知道在调用Read之前必须先达到S的SetLength。

Note:
I know both are having the same result.
I know that I have to SetLength of S before calling Read.

更新

S是AnsiString。

S is AnsiString.

这里是完整功能:

{从文件中读取一堆字符。为什么选择 ReadChars而不选择 ReadString?此函数读取C ++字符串(字符串的长度也未写入磁盘)。因此,我必须给出要读取的字符数作为参数。 }

{ Reads a bunch of chars from the file. Why 'ReadChars' and not 'ReadString'? This function reads C++ strings (the length of the string was not written to disk also). So, i have to give the number of chars to read as parameter. }

function TMyStream.ReadChars(out s: AnsiString; CONST Count: Longint): Boolean; 
begin
 SetLength(s, Count);
 Result:= Read(s[1], Count)= Count;
end;

速度测试

在我的速度测试中,第一种方法比第二种方法快一点。我使用了一个400MB的文件,从中读取了大约200000次字符串。该过程设置为高优先级。

In my speed test the first approach was a tiny bit faster than the second one. I used a 400MB file from which I read strings about 200000 times. The process was set to High priority.

有史以来最好的读取时间是:

变量B为1.35,变量A为1.37。

平均值:

平均而言,B的得分也比A高20毫秒。

The best read time ever was:
1.35 for variant B and 1.37 for variant A.
Average:
On average, B was scoring also 20ms better than A.

每个变体重复测试15次。

The test was repeated 15 times for each variant.

差别确实很小。可能会落入测量误差范围内。
如果我更频繁地从更大的文件中读取字符串,可能会很有意义。
但是,暂时来说,这两行代码的性能相同。

The difference is really small. It could fall into the measuring error range. Probably it will be significant if I read strings more often and from a bigger file. But for the moment let's say that both lines of code are performing the same.

ANSWER

变体A-可能快一点点
变体B-(显然)更容易阅读,而且更像Delphi。我的首选。

ANSWER
Variant A - might be a tiny tiny bit faster Variant B - is (obviously) much more easier to read and it is more Delphi-ish. My preferred.

注意:

我已经看到Embarcadero在TStreamReadBuffer示例中使用变体A,但是使用了TBytes而不是String。

Note:
I have seen Embarcadero using variant A in TStreamReadBuffer example, but with a TBytes instead of String.

推荐答案

请注意,在运行时

1. DiskStream.Read(Pointer(s)^, Count)
2. DiskStream.Read(s[1], Count)

1。版本会更快。

但是您必须确保 s 变量是显式本地的,或者您在循环之前已将自己命名为 UniqueString

But you must be sure that the s variable is explicitly local, or you have called yourself UniqueString(s) before the loop.

由于指针^ 不会调用 UniqueString?()低级隐藏RTL调用,它会比 s [1] 快,但是如果 s您可以覆盖一些现有数据 code>字符串变量在当前上下文和其他上下文之间共享(例如,如果 s 的最后一个内容是从属性值或 s 作为参数发送到另一种方法)。

Since pointer(s)^ won't call UniqueString?() low-level hidden RTL call, it will be faster than s[1], but you may override some existing data if the s string variable is shared between the current context and other context (e.g. if the last content of s was retrieved from a function from a property value, or s is sent as parameter to another method).

事实上,最快的正确编码方式是读取 AnsiString 的内容是:

In fact the fastest correct way of coding this reading an AnsiString from content is:

  s := '';
  SetLength(s,Count);
  DiskStream.Read(pointer(s)^,Count);

  SetString(s,nil,Count);
  DiskStream.Read(pointer(s)^,Count);

第二个版本等于第一个,但少一行。

The 2nd version being equal to the 1st, but with one line less.

s 设置为''将调用 FreeMem()+ AllocMem()而不是 SetLength()中的 ReallocMem(),因此可以避免调用 move(),因此会更快一些。

Setting s to '' will call FreeMem()+AllocMem() instead of ReallocMem() in SetLength(), so will avoid a call to move(), and will be therefore a bit faster.

实际上, UniqueString?( ) s [1] 生成的RTL调用将非常快,因为您已经调用了 SetLength()在调用它之前:因此, s 已经是唯一的,并且 UniqueString?() RTL调用将几乎立即返回。分析后,两个版本之间的速度差异不大:几乎所有时间都花在字符串分配和从磁盘上移动内容上。也许发现 s [1] 更无聊。

In fact, the UniqueString?() RTL call generated by s[1] will be very fast, since you have already called SetLength() before calling it: therefore, s is already unique, and UniqueString?() RTL call will return almost immediately. After profiling, there is not much speed difference between the two versions: almost all time is spend in string allocation and content moving from disk. Perhaps s[1] is found to be more "pascalish".

这篇关于指针^与s [1]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆