我在 Delphi XE2中工作,我必须创建一个复杂的函数,有时复制字符串的较长部分,有时只复制字符。这取决于源字符串的内容。因此,问题是哪个示例方法更快?第一个我也很好奇运行时间的差异有多大。
6gpjuf901#
Move()的替代方法--即使Move()被简单地写成了一个逐字节循环(它不在RTL中,尽管有很多优化空间,我们可能很快就会得到(tm))--也会更快,因为对于每一个对string的索引写操作,编译器都会插入一个对System._UniqueStringU()的调用。要将string的一部分(如果是连续的)复制到新的string中,我可能会使用System.Copy()或System.SetString()。然而,如果性能很重要,我的直觉告诉我,这部分可能不值得优化,而是减少string的使用并将其部分复制为新的string。在.NET中,这就是他们实现Span<T>的原因,Span<T>基本上是一个长度受限的指针。在处理string解析之类的事情时,使用这种方法比优化复制本身更能提高性能。额外的好处:如果你这样写循环,你就省略了_UniqueStringU()调用,因为SetLength()之前已经保证了Result是一个字符串,其中RefCount = 1:
Move()
string
System._UniqueStringU()
System.Copy()
System.SetString()
Span<T>
_UniqueStringU()
SetLength()
Result
RefCount = 1
Len := Length(Str); SetLength(Result, Len); for I := 1 to Len do PChar(Pointer(Result))[I-1] := Str[I];
我首先使用到Pointer的转换,以避免编译器在执行string到PChar的转换时插入_UStrToPWChar()调用。
Pointer
PChar
_UStrToPWChar()
1条答案
按热度按时间6gpjuf901#
Move()
的替代方法--即使Move()
被简单地写成了一个逐字节循环(它不在RTL中,尽管有很多优化空间,我们可能很快就会得到(tm))--也会更快,因为对于每一个对string
的索引写操作,编译器都会插入一个对System._UniqueStringU()
的调用。要将
string
的一部分(如果是连续的)复制到新的string
中,我可能会使用System.Copy()
或System.SetString()
。然而,如果性能很重要,我的直觉告诉我,这部分可能不值得优化,而是减少
string
的使用并将其部分复制为新的string
。在.NET中,这就是他们实现Span<T>
的原因,Span<T>
基本上是一个长度受限的指针。在处理string
解析之类的事情时,使用这种方法比优化复制本身更能提高性能。额外的好处:如果你这样写循环,你就省略了
_UniqueStringU()
调用,因为SetLength()
之前已经保证了Result
是一个字符串,其中RefCount = 1
:我首先使用到
Pointer
的转换,以避免编译器在执行string
到PChar
的转换时插入_UStrToPWChar()
调用。