cat /proc/meminfo
MemTotal:3981272 kB
我在python中运行了这个简单的测试
#!/usr/bin/env python
import sys
num = int(sys.argv[1])
li = []
for i in xrange(num):
li.append(i)
$ time ./listappend.py 1000000
real 0m0.342s
user 0m0.304s
sys 0m0.036s
$ time ./listappend.py 2000000
real 0m0.646s
user 0m0.556s
sys 0m0.084s
$ time ./listappend.py 4000000
real 0m1.254s
user 0m1.136s
sys 0m0.116s
$ time ./listappend.py 8000000
real 0m2.424s
user 0m2.176s
sys 0m0.236s
$ time ./listappend.py 16000000
real 0m4.832s
user 0m4.364s
sys 0m0.452s
$ time ./listappend.py 32000000
real 0m9.737s
user 0m8.637s
sys 0m1.028s
$ time ./listappend.py 64000000
real 0m56.296s
user 0m17.797s
sys 0m3.180s
问题:
64000000的时间是32000000的时间的6倍,但在此之前,时间只是倍增。为什么这样?
答案 0 :(得分:6)
TL;DR - Due to RAM being insufficient & the memory being swapped out to secondary storage.
我在我的盒子上运行了不同大小的程序。结果如下
/usr/bin/time ./test.py 16000000
2.90user 0.26system 0:03.17elapsed 99%CPU 513480maxresident
0inputs+0outputs (0major+128715minor)pagefaults
/usr/bin/time ./test.py 32000000
6.10 user 0.49 system 0:06.64 elapsed 99%CPU 1022664maxresident
40inputs (2major+255998minor)pagefaults
/usr/bin/time ./test.py 64000000
12.70 user 0.98 system 0:14.09 elapsed 97%CPU 2040132maxresident
4272inputs (22major+510643minor)pagefaults
/usr/bin/time ./test.py 128000000
30.57 user 23.29 system 27:12.32 elapsed 3%CPU 3132276maxresident
19764880inputs (389184major+4129375minor)pagefaults
User time
程序作为用户运行的时间。 (运行用户逻辑)System time
程序作为系统执行的时间。 (即系统调用所花费的时间) Elapsed time
程序执行的总时间。 (包括等待时间..)
Elapsed time = User time + System Time + time spent waiting
Major Page Fault
当一页内存不在RAM&必须从硬盘等辅助设备中获取。
16M列表大小:列表主要在内存中。因此没有页面错误。
由于unutbu指出python解释器在列表增加时为列表分配O(n*n)
额外空间,情况只会恶化。
答案 1 :(得分:4)
根据effbot:
将项目附加到列表所需的时间是“摊销常数”; 每当列表需要分配更多内存时,它就会分配空间 一些项目超过实际需要,以避免重新分配 在每次调用时(这假设内存分配器很快;对于巨大的 列表,分配开销可能会将行为推向 O(n * n))。
(我的重点)。
当您向列表中添加更多项目时,重新分配器将尝试保留更大量的内存。一旦消耗了所有物理内存(RAM)并且操作系统开始使用交换空间,从磁盘到RAM的数据混乱或反之亦然会使您的程序变得非常慢。
答案 2 :(得分:0)
我强烈怀疑您的Python进程耗尽了可用的物理RAM,并开始交换到磁盘。
重新运行最后一次测试,同时密切关注其内存使用情况和/或页面错误次数。