2

我写了以下脚本

基本上,我只是在为机器学习学习 Python,并想检查计算密集型任务的执行情况。我观察到对于 10**8 次迭代,Python 占用了大量 RAM(大约 3.8 GB)和大量 CPU 时间(只是冻结了我的系统)

我想知道是否有任何方法可以通过代码或一些全局设置来限制时间/内存消耗

脚本 -

initial_start = time.clock()
for i in range(9):
 start = time.clock()
 for j in range(10**i):
  pass
 stop = time.clock()
 print 'Looping exp(',i,') times takes', stop - start, 'seconds'
final_stop = time.clock()
print 'Overall program time is',final_stop - initial_start,'seconds'
4

5 回答 5

7

在 Python 2 中,range创建一个列表。改为使用xrange。有关更详细的说明,请参阅您是否应该始终偏爱 xrange() 而不是 range()?

请注意,无操作 for 循环是一个非常糟糕的基准测试,它几乎不会告诉您有关 Python 的任何信息。

另请注意,根据 gnibbler 的评论,Python 3 的range工作方式与 Python 2 的xrange.

于 2012-08-15T19:36:26.170 回答
2

看这个问题:如何限制堆大小?

为了解决您的脚本,timeit 模块测量更准确地执行操作所需的时间

>>> import timeit
>>> for i in range(9):
...     print timeit.timeit(stmt='pass', number=10**i)
...
0.0
0.0
0.0
0.0
0.0
0.015625
0.0625
0.468752861023
2.98439407349

您的示例大部分时间都在处理您要记忆的巨大数字列表。 xrange而不是range将有助于解决该问题,但您仍在使用糟糕的基准。循环将一遍又一遍地执行,实际上并没有做任何事情,所以 cpu 正忙于检查条件并进入循环。

如您所见,创建这些列表需要花费大部分时间

>>> timeit.timeit(stmt='range(10**7)', number=1)
0.71875405311584473
>>> timeit.timeit(stmt='for i in range(10**7): pass', number=1)
1.093757152557373
于 2012-08-15T19:56:16.483 回答
2

Python 占用 RAM,因为您正在使用range函数创建一个 10 ** 8 长度的非常大的列表。这就是迭代器变得有用的地方。

使用xrange而不是range.

它的工作方式与rangedo 相同,但不是在内存中创建那个大列表,xrange而是只计算内部索引(每次迭代将其值增加 1)。

于 2012-08-15T19:38:10.390 回答
1

如果您正在考虑使用 Python 进行机器学习,请查看numpy。它的理念是在优化的 C 中实现所有“内部循环”(矩阵运算、线性代数),并使用 Python 来操作输入和输出并管理高级算法——有点像使用 Python 的 Matlab。这为您提供了两全其美的优势:Python 的易用性和可读性以及 C 的速度。

回到您的问题,对 numpy 操作进行基准测试将使您对 Python 在机器学习方面的性能进行更真实的评估。

于 2012-08-15T20:44:34.037 回答
0

至于 cpu,你有一个 for 循环运行数十亿次迭代,中间没有任何睡眠或暂停,所以难怪该进程完全占用 cpu(至少在单核计算机上)。

于 2012-08-15T19:57:20.337 回答