Pointer(s)^ versus s[1]

前端 未结 7 985
南旧
南旧 2021-02-12 14:56

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

A) DiskStream.Read(Pointer(s         


        
7条回答
  •  北海茫月
    2021-02-12 15:01

    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".

提交回复
热议问题