Perl允许预分配数组。我们可以在使用之前预先分配数组,然后我们可以添加更多的元素。例如,分配50个阵列成员,然后添加第51个成员,因为阵列是可扩展的。那么preallocating阵列提高性能?在perl中为数组预分配内存有什么用?
回答
这是因为计算机中的内存分配方式。计算机内存就像白板上的空间:它与其他内存有关;它不能被移动,它必须被复制。
如果你创建一个小的阵列可能是这样的:
@array = (1, 4, 8, 12, 19);
allocate memory for @array
______________________| |______| a b c|__________
copy in the data
______________________| 1 4 8 12 19|______| a b c|__________
_
是未分配的内存。 |
表示分配给数组的内容的界限。 | a b c|
是一些其他数组。
然后,如果您推入该数组几次,Perl将不得不重新分配内存。在这种情况下,它可以增加已经存在的未分配空间的内存。
push @array, 23, 42;
grow the existing memory
______________________| 1 4 8 12 19 | a b c|__________
add the new data
______________________| 1 4 8 12 19 23 42| a b c|__________
现在,如果你把更多的数字到@array
会发生什么?它不能再增长你的记忆力了,还有另外一个阵列。所以,就像在白板上一样,它必须将整个阵列复制到一个清晰的内存块。
push @array, 85, 99;
Allocate a new chunk of memory
| | 1 4 8 12 19 23 42| a b c|__________
Copy the existing data
| 1 4 8 12 19 23 42 | 1 4 8 12 19 23 42| a b c|__________
Deallocate the old memory
| 1 4 8 12 19 23 42 |__1__4__8_12_19_23_42| a b c|__________
Add the new data
| 1 4 8 12 19 23 42 85 99|__1__4__8_12_19_23_42| a b c|__________
为了节省时间,Perl不会花费时间擦除旧数据。它只会释放它,当他们需要时,其他东西可以在它上面涂写。
这使推送更昂贵,尤其是对于需要复制更多数据的非常大的数组。随着数组越来越大,Perl越来越可能不得不分配一大块内存并复制所有内容。
还有一个问题:内存碎片。如果你一次又一次地分配和重新分配内存块,那么很难找到大块空闲的内存。这在现代操作系统上不是什么问题,但仍然是一个问题。它可以使您看起来内存少于实际使用的内存量,并且可能导致操作系统将磁盘用作内存(虚拟内存)而不是它应该使用的内存。磁盘比内存慢。
我简化了很多东西。我让它看起来像Perl必须重新分配每当你push
。这是不正确的。正因为这个原因,Perl为数组分配更多的内存。因此,您可以安全地向数组添加一些额外的条目,而不必重新分配Perl。对于字符串和哈希也是如此。
另一件事是,这可能是一个过时的观点,如何分配内存在现代操作系统上工作......虽然Perl有时会做自己的内存分配,如果它不信任操作系统。检查use Config; print $Config{usemymalloc}
。 n
表示Perl正在使用操作系统的内存分配,y
表示它正在使用Perl的。
经验法则是:不要预先分配,这可能是浪费你的时间和计算机的内存。但是,如果全部为以下条件为真,请查看预分配是否有帮助。
- 您profiled并发现问题。
- 您正在通过增加数据结构来逐步构建数据结构。
- 你肯定知道它的最小尺寸。
- 这个大小是“大”。
什么是“大”是争论和取决于您的Perl版本,您的操作系统,您的硬件和性能容忍。
- 1. 为什么.net在初始化2d数组时分配内存?
- 2. 为数组分配内存
- 3. 为什么.append()比在预分配数组中设置值慢?
- 4. 为什么数组大于分配给它的内存?
- 5. 为什么BitmapData.copyPixels会分配内存?
- 6. 为什么我们用int数据为链表分配内存?
- 7. 为什么没有分配原始数据类型的内存?
- 8. 在类定义中动态分配内存有什么作用?
- 9. 为什么Jetty不使用所有分配的内存?
- 10. 为什么用malloc分配的虚拟内存没有发布?
- 11. 为多维数组分配内存
- 12. 为结构数组分配内存
- 13. 内存分配给数组
- 14. numpy数组内存分配
- 15. std :: shared_ptr预分配内存
- 16. 为什么不预先分配内存就可以使用堆栈?
- 17. 内存竞技场和内存分配器有什么区别?
- 18. 内存分配:为什么这个C程序有效?
- 19. 在函数中分配的内存会发生什么?
- 20. 为什么Perl会按照这种模式重新分配内存?
- 21. 用于数组的C++内存分配
- 22. 内存分配使用数组
- 23. 使用数组的内存分配
- 24. C中的数组的内存分配
- 25. 用c中的数组进行LIFO内存分配的目的是什么?
- 26. 在C#中重新分配数组时,内存会发生什么变化?
- 27. phpunit:什么时候有用预计任何()?,为什么存在?
- 28. 预分配内存并在分叉进程中使用。
- 29. 在大对象堆内存中预分配一些内存
- 30. 使用指针为C中的3D数组分配内存?