TStringList与array of String与TArrayOfString之间的区别

9
我正在对一个Inno Setup项目进行重构,有一些不太清楚的东西是TArrayOfString、字符串数组和TStringList的使用。这三种类型之间有什么区别?据我所知,在使用它们时似乎没有什么区别。所有三种类型都存储字符串,我可以像这样使用数组\列表获取存储的字符串:arrayName[i]
在速度方面是否有差异或者在使用其中一种类型时是否被认为是糟糕的编码方式呢?希望有人能够在这方面为我带来明确的解释。
1个回答

16

1. 差异

TArrayOfString 类型是 array of string 的别名,因此它们相等(你可以在源代码这里看到)。TStringList 类是一个索引字符串集合类,其内部存储为一个记录数组。但是,string 数组和 TStringList 类之间有很大的区别。

array of string 只是一种用于存储字符串元素的索引方式,而 TStringList 类是一种集合类,提供了多个内容处理任务的选项和方法(例如消除重复项、排序、搜索等)。

2. 性能

如果我们忽略 TStringList 类提供的方法,将其视为一种存储方式,那么在比较性能时,我们必须关注在应用程序中如何向该存储添加字符串元素。

通常情况下,只要不频繁调整数组大小,array 类型就会更快,例如当经常调用时,单个元素的添加效率并不高:

procedure AddSingleElement(var A: array of string; const S: string);
begin
  SetArrayLength(A, GetArrayLength(A) + 1);
  A[High(A)] := S;
end;

这是因为保存数组的内存被重新分配了。这会花费一些时间。但如果您不经常设置数组长度,就可以防止这种瓶颈。理想情况是仅在设置目标长度时设置数组长度一次(当然需要提前知道元素计数)。

另一个改善上述代码的选项(当您事先不知道元素数量时)是预分配一些元素的数组长度。这将减少重新分配的数量,但也需要您记住并操作长度,该长度应该是“逻辑实际”数组长度。当您添加项时,TStringList类为您完成了这一过程。

如果您向TStringList对象添加项目,则字符串列表会检查是否有足够的空间,如果没有,则通过一些元素增加其内部数组的长度(从而消除所描述的重新分配性能问题)。

但它并不像听起来那么关键,只有在使用非常长的字符串和非常长的数组(成千上万的元素,可能是真正长的字符串)时才会注意到性能问题。我不想在这里具体说明数字,因为我认为您在设置应用程序时不应该需要这些数字。

3. 结论

总之,数组是更快的存储方式,但应避免频繁调整其大小。如果您真的非常关心性能,请仅分配一次它们的大小(如果您事先知道元素数量),或更少地按更多元素进行频繁调整(这需要更多编码)。

TStringList类输掉了这场性能比赛(仅因为它是数组的包装器),但它在逐一添加项时有效地调整其内部存储(而无需为数组自己编写此代码)。

4. 经验法则

作为经验法则,我建议在事先知道元素数量或不经常更改其长度时使用数组。当您无法满足该要求或需要其中一些内置内容处理例程时,请使用字符串列表。


非常好的答案,谢谢。你真的是一个“超凡班级”的人 ;) - Bongo
不客气!那个昵称来自捷克语,它是“Lama”的类类型(使用T前缀)。将它们组合在一起就是“tlama”,这赋予了它一个不同的含义 :) - TLama

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接