我在一些Rebol代码中找到了这样的一行:
dups: make block! 10000
为什么要在Rebol中使用预分配?
写作时出了什么问题:
dups: copy []
答案 0 :(得分:7)
第一件事:你没有在Rebol中“分配一个变量”,你“预先分配一个系列缓冲区”(恰好在你的代码示例中由一个单词引用,但它可能只是在一个块中)。
快速回答:每次向系列插入或附加数据时,如果系列缓冲区已满,则系列将由内存管理器重新分配给更大的系列缓冲区。如果你多次扩展一个系列(比如在循环中将数据附加到系列中),如果你没有预先分配,你最终可能会为所有的重新分配消耗大量的额外内存,并且可能在某些时候,还会触发垃圾收集器通行证。这通常会导致程序执行速度大幅下降,并消耗大量额外内存。将串行缓冲区预先分配到足够大的大小以容纳所有最终数据,将避免所有这些内存和性能问题。
在dups: copy []
的情况下,您正在分配一个最小系列缓冲区(大小可能是8或16个插槽),因此如果您的所有数据都不适合此缓冲区,您的程序将支付(沉重的)重新分配的成本。另外[]
是一个预先分配的最小大小的文字系列,你只是用它作为模板来构建一个新系列,所以最好避免浪费内存,而不是编写代码:dups: make block! 0
这将分配一个块!系列最小尺寸,不浪费额外的块!系列。
答案 1 :(得分:2)
预分配缓冲区对于低级函数read-io
至关重要如果您需要,例如在读取数据时访问确切的错误代码,您可以使用read-io而不是在打开的端口上复制。
read-io与c语言的READ相当。 您为read-io提供了预先分配的固定缓冲区和缓冲区长度。 如果您尝试使用缓冲区长度超过预分配的read-io,那么您自己承担风险
答案 2 :(得分:0)
我刚刚测试了
>> a: make block! 10000
>> b: copy []
>> delta-time [loop 10000 [append a 1]]
== 0:00:00.004315
>> delta-time [loop 10000 [append b 1]]
== 0:00:00.005795
差异只有不到百分之一秒。
然后我重新启动了rebol并进行了测试:
>> a: make block! 10000
>> b: copy []
>> delta-time [loop 20000 [append a "test"]]
== 0:00:00.000238
>> delta-time [loop 20000 [append b "test"]]
== 0:00:00.000223
预分配比预分配更快!
答案 3 :(得分:-1)
我同意Ladislav的观点,可能 delta-time 不可靠。但是我不认为现代PC需要预先分配,因为简单的浏览器插件浪费了大量的内存。我相信Rebol垃圾收集器足以供普通使用。 (也许在Android设备上速度和内存仍然存在问题)