列表到字符串的转换 - TCL
Conversion of list to string - TCL
我在TCL遇到了以下问题。在我的应用程序中,我将非常大的文本文件(大约数百 MB)读入 TCl 列表。该列表然后由函数返回到主上下文,然后检查是否为空。这是代码快照:
set merged_trace_list [merge_trace_files $exclude_trace_file $trace_filenames ]
if {$merged_trace_list == ""} {
...
我在 "if" 行崩溃了。崩溃似乎与内存溢出有关。我认为与“”的比较会强制 TCL 将列表转换为字符串,并且由于字符串太长,这会导致崩溃。然后我用另一行替换了上面的 "if" 行:
if {[lempty $merged_trace_list]} {
崩溃确实消失了。综上所述,我有几个问题:
- TCL 允许的最大字符串长度是多少?
- TCL中string和list在内存分配上有什么区别?为什么我可以有很长的列表,却没有相应的字符串?
- 当函数第一次返回的列表进入主作用域时(第一行),是不是先转换成字符串?如果是,为什么我在那行没有崩溃?
谢谢,
我希望描述和问题都清楚。
康斯坦丁
这不是一个真正的答案,但对于评论来说有点太多了。
如果要检查列表是否为空,最好的选择是llength
。如果列表长度为 0,则您的列表没有内容。对此的低级查找非常便宜。
如果您仍想通过将列表与空字符串进行比较来确定列表是否为空,则您将不得不面对解析列表的字符串表示形式的成本。在这种情况下,$myLongList eq {}
比 $myLongList == {}
更可取,因为后者的比较还强制解释器检查操作数是否为数字(至少以前是这样,它可能已经改变了)。
单个内存对象(例如字符串)的当前最大大小为 2GB。 这是 64 位平台上的一个已知错误(长期存在),但修复它需要重要的 ABI 和 API 重大更改,因此直到 Tcl 才会出现9.0.
字符串和列表的区别在于字符串存储在单个内存块中,而列表存储在指向元素的指针数组中。您可能可以在列表中获取 256k 个元素没问题,但之后您可能 运行 遇到问题,因为数组达到 2GB 限制。
Tcl 的值对象可能同时是 列表和字符串;关于 Tcl 的格言“一切都是字符串”实际上并不正确,只是一切都可以序列化为字符串。列表的返回不会强制将其转换为字符串——这实际上是一个相当慢的操作——但是将相等的值与字符串进行比较 确实 强制生成字符串。 lempty
命令必须改为获取字符串的长度(您可以使用 llength
来做同样的事情)并将其与零进行比较。
您能否调整您的程序,使其不需要一次将所有数据保存在内存中?上面提到的bug,它的生活有点危险。
我在TCL遇到了以下问题。在我的应用程序中,我将非常大的文本文件(大约数百 MB)读入 TCl 列表。该列表然后由函数返回到主上下文,然后检查是否为空。这是代码快照:
set merged_trace_list [merge_trace_files $exclude_trace_file $trace_filenames ]
if {$merged_trace_list == ""} {
...
我在 "if" 行崩溃了。崩溃似乎与内存溢出有关。我认为与“”的比较会强制 TCL 将列表转换为字符串,并且由于字符串太长,这会导致崩溃。然后我用另一行替换了上面的 "if" 行:
if {[lempty $merged_trace_list]} {
崩溃确实消失了。综上所述,我有几个问题:
- TCL 允许的最大字符串长度是多少?
- TCL中string和list在内存分配上有什么区别?为什么我可以有很长的列表,却没有相应的字符串?
- 当函数第一次返回的列表进入主作用域时(第一行),是不是先转换成字符串?如果是,为什么我在那行没有崩溃?
谢谢, 我希望描述和问题都清楚。
康斯坦丁
这不是一个真正的答案,但对于评论来说有点太多了。
如果要检查列表是否为空,最好的选择是llength
。如果列表长度为 0,则您的列表没有内容。对此的低级查找非常便宜。
如果您仍想通过将列表与空字符串进行比较来确定列表是否为空,则您将不得不面对解析列表的字符串表示形式的成本。在这种情况下,$myLongList eq {}
比 $myLongList == {}
更可取,因为后者的比较还强制解释器检查操作数是否为数字(至少以前是这样,它可能已经改变了)。
单个内存对象(例如字符串)的当前最大大小为 2GB。 这是 64 位平台上的一个已知错误(长期存在),但修复它需要重要的 ABI 和 API 重大更改,因此直到 Tcl 才会出现9.0.
字符串和列表的区别在于字符串存储在单个内存块中,而列表存储在指向元素的指针数组中。您可能可以在列表中获取 256k 个元素没问题,但之后您可能 运行 遇到问题,因为数组达到 2GB 限制。
Tcl 的值对象可能同时是 列表和字符串;关于 Tcl 的格言“一切都是字符串”实际上并不正确,只是一切都可以序列化为字符串。列表的返回不会强制将其转换为字符串——这实际上是一个相当慢的操作——但是将相等的值与字符串进行比较 确实 强制生成字符串。 lempty
命令必须改为获取字符串的长度(您可以使用 llength
来做同样的事情)并将其与零进行比较。
您能否调整您的程序,使其不需要一次将所有数据保存在内存中?上面提到的bug,它的生活有点危险。