In a function that reads data (data meaning exclusively strings) from disk, which should I prefer? Which is better?
A) DiskStream.Read(Pointer(s
Be aware that when running
1. DiskStream.Read(Pointer(s)^, Count)
2. DiskStream.Read(s[1], Count)
The 1. version will be faster.
But you must be sure that the s
variable is explicitly local, or you have called yourself UniqueString(s)
before the loop.
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).
In fact the fastest correct way of coding this reading an AnsiString
from content is:
s := '';
SetLength(s,Count);
DiskStream.Read(pointer(s)^,Count);
or
SetString(s,nil,Count);
DiskStream.Read(pointer(s)^,Count);
The 2nd version being equal to the 1st, but with one line less.
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.
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".