将列表转换为字符串 - TCL

时间:2015-10-24 17:26:51

标签: string list tcl

我在TCL遇到了以下问题。在我的应用程序中,我将非常大的文本文件(几百MB)读入TCl列表。然后该函数将该列表返回到主上下文,然后检查空白。这是代码快照:

set merged_trace_list [merge_trace_files $exclude_trace_file $trace_filenames ]

if {$merged_trace_list == ""} { ...

我在"如果"线。崩溃似乎与内存溢出有关。我认为与""的比较强制TCL将列表转换为字符串,由于字符串太长,这会导致崩溃。然后我替换了上面的"如果"换另一个:

if {[lempty $merged_trace_list]} {

崩溃确实消失了。鉴于上述情况,我有几个问题:

  1. TCL中允许的最大字符串长度是多少?
  2. 在内存分配方面,TCL中字符串和列表有什么区别?为什么我可以有很长的列表,但没有相应的字符串?
  3. 当函数首先将函数返回到主作用域(第一行)时,它是否先没有转换为字符串?如果是的话,为什么我不会在那条线上崩溃?
  4. 谢谢, 我希望描述和问题都清楚。

    康斯坦丁

2 个答案:

答案 0 :(得分:3)

单个内存对象(例如,字符串)的当前最大大小为2GB。 这是64位平台上的一个已知错误(长期存在),但修复它需要进行重大的ABI和API更改,因此在Tcl 9.0之前不会出现。

字符串和列表之间的区别在于字符串存储在单个内存块中,而列表存储在指向元素的指针数组中。您可以在列表中获得256k元素没问题,但在此之后,当阵列达到2GB限制时,您可能会遇到问题。

Tcl的值对象可以同时同时包含列表和字符串;关于Tcl的“一切都是字符串”的格言并不是真的,只是所有东西都可以序列化为字符串。返回列表不会强制它转换为字符串 - 这实际上是一个相当慢的操作 - 但是将相等的值与字符串进行比较会强制生成字符串。 lempty命令必须改为获取字符串的长度(您可以使用llength执行相同的操作)并将其与零进行比较。

您是否可以将程序调整为不需要立即将所有数据保存在内存中?考虑到上面提到的错误,它的生活有点危险。

答案 1 :(得分:1)

这不是一个真正的答案,但对评论来说有点太多了。

如果要检查列表是否为空,则最佳选项为llength。如果列表长度为0,则列表中没有内容。对此的低级查找非常便宜。

如果您仍想通过将列表与空字符串进行比较来确定列表是否为空,则必须面对解析列表的字符串表示的成本。在这种情况下,$myLongList eq {}优于$myLongList == {},因为后者的比较也会强制解释器检查操作数是否为数字(至少它曾经是这样,它可能已经改变了)。 / p>