【问题标题】:TCL max size of arrayTCL最大数组大小
【发布时间】:2015-07-09 10:26:14
【问题描述】:

我正在开发一个工程应用程序,界面是用 TCL TK 编写的。

在我需要使用(非常)大的数组之前,一切都很顺利。 370.000.000 个元素,每个元素的长度为 2 到 10 个字符(线性增长)。

我的问题是,¿TCL 数组的大小限制在哪里? 我一直在阅读和调查,我唯一发现的是“2GB”的字符串数据,但我不知道它是否可靠,因为它没有解释原因。

我做了一个实验:

set lista [list ]
catch {
    for {set i 0} {$i < 370000000} {incr i} {
        lappend lista $i
    }
}
puts $i

在 32 位 Windows 7 上或多或少地返回 $i = 50.000.000

【问题讨论】:

    标签: arrays size tcl limit


    【解决方案1】:

    解释起来有点复杂。 2GB 限制来自低级内存分配器,它有大小限制,因为它使用 signed 32 位整数来描述要分配多少内存。这在 32 位系统上很好,但在 64 位系统上仍然是这样,这是一个开放的错误(可能分配给我); C API 中的正确类型实际上是 ssize_t(是的,仍然有符号;负值用于发出信号)但修复它完全破坏了很多 API,因此需要进行主要版本更改才能解决。

    但列表的最大大小是另一回事。这从根本上与几件事的结合有关。首先,可以分配的内存结构的最大大小(2GB 限制)意味着您可能无法可靠地在 64 位系统上的列表中获得超过 256M 的元素。然后是分配的项目总数,尽管这在实践中问题不大,特别是如果您实际上将项目多次放入列表中(因为它们共享引用)。最后,还有列表的字符串表示的大小:如果您生成了很多,那么无论如何您都做错了,但是如果您正在创建它,那将是您的示例中真正的限制因素(因为这将尽快达到 2GB 的限制)。

    您达到内存限制的实际点可能会更低,具体取决于您的系统何时开始拒绝分配内存的请求。这完全取决于操作系统,它倾向于根据系统上发生的其他事情来做出决定,因此难以置信很难在那里给出任何类型的一般规则。我的(64 位,OSX)系统花了很长时间,但成功运行了您的示例代码:

    $ tclsh8.6
    % eval {
    set lista [list ]
    catch {
        for {set i 0} {$i < 370000000} {incr i} {
            lappend lista $i
        }
    }
    puts $i
    }
    370000000
    % llength $lista
    370000000
    % unset lista
    % exit
    

    llength 是唯一真正快速的操作(因为它可以从列表元数据中提取长度)。 unset 花了很长时间。 exit 很快,但花了几秒钟。

    【讨论】:

    • 很高兴直接从这个双手插在系统内部的人那里得到答案。
    • 谢谢先生。 @donal-fellows,过去 5 年我一直使用 TCL 作为我的主要编程语言,还有很多东西要学。
    • 我用了20年了,还是什么都不懂。 :-)
    猜你喜欢
    • 1970-01-01
    • 2012-04-06
    • 1970-01-01
    • 2010-10-24
    • 1970-01-01
    • 1970-01-01
    • 2011-09-03
    • 2011-01-20
    • 2015-11-26
    相关资源
    最近更新 更多