5

我很好奇 Delphi 2010 中这段代码会发生什么:

function foo: WideString;
var 
   myUnicodeString: UnicodeString; 
begin
  for i:=1 to 1000 do
  begin
    myUnicodeString := ... something ...;

    result := result + myUnicodeString;  // This is where I'm interested
  end;
end;

涉及多少个字符串转换,在性能方面是否特别糟糕?

我知道该函数应该只返回 a UnicodeString,但我在 VCL 流代码中看到了这种反模式,并想了解这个过程。

4

2 回答 2

10

要回答您关于代码实际在做什么的问题,请使用以下语句:

result := result + myUnicodeString;

执行以下操作:

  1. 调用System._UStrFromWStr()转换Result为临时UnicodeString

  2. 调用System._UStrCat()连接myUnicodeString到 temp

  3. 调用System._WStrFromUStr()将 temp 转换为 aWideString并将其分配回Result.

有一个System._WStrCat()用于将 a 连接WideString到 a WideString(和System._UStrCat()for UnicodeString)的函数。如果 CodeGear/Embarcadero 对此更聪明,他们可以实现一个将 a作为输入和 a作为输出的System._WStrCat()重载(反之亦然,将 a 连接到 a 上)。这样,就不再需要临时转换了。两者和都被编码为 UTF-16(大多数情况下,但我不会在这里讨论),因此将它们连接在一起只是一个分配和移动的问题,就像将两个s 或两个s 连接在一起时一样。UnicodeStringWideStringWideStringUnicodeStringUnicodeStringWideStringUnicodeStringUnicodeStringWideString

于 2013-08-15T18:22:57.407 回答
4

性能很差。不需要任何编码转换,因为一切都是 UTF-16 编码的。但是,WideString 是 COM BSTR 类型的包装器,其性能比本机 UnicodeString 差。

自然,您应该更喜欢使用本机类型(UnicodeString 或 TStringBuilder)完成所有工作,并在可能的最后一刻转换为 WideString。

这通常是一个好政策。您不想在内部使用 WideString,因为它纯粹是一种互操作类型。因此,仅在互操作边界处转换为(和来自)WideString。

于 2013-08-15T15:40:19.967 回答