【问题标题】:Exponential calculation in PythonPython中的指数计算
【发布时间】:2015-05-05 22:48:00
【问题描述】:

在尝试Euler 99 时,我注意到这些操作需要不同的时间:

>>> 632382**518061  # never finishes..

>>> 632382**518061 > 519432**525806  # finishes in few seconds
True

我想知道这是什么原因?

【问题讨论】:

  • 作为一个附带问题,当 Python 编译器看到 632382**518061 时,它会想,“嘿,对两个小的整数文字进行简单操作,我将在编译时执行此操作并对其进行常量折叠”。因此,编译该行代码需要大约 3 秒,但运行它只需要 20 纳秒(然后格式化要打印的字符串需要 200 秒……)。在交互式解释器上没关系(除非您尝试使用timeit 进行基准测试),但将其放入一个模块和import 该模块中,第一次需要3 秒,但如果你再做一次(即使在退出并重新启动后)也不会。
  • 顺便说一句,即使没有阅读问题 99,我怀疑它的重点是给你的数字太大而无法实际计算,所以你必须知道和/或查找并学习一些像模幂运算或从每一边除以因子,仅在没有公因子时计算或估计然后测试误差范围的技巧。
  • 在第一个示例中尝试显示多位数字时,内存和时间都会受到影响。第二,没有尝试实际显示,只是简单的比较,不会像打印到标准输出那样耗费时间。

标签: python optimization largenumber exponentiation


【解决方案1】:

问题是 python 试图打印第一个结果。但是这个数字有无数个数字,python 不会刷新输出,直到遇到换行符,这是在将所有数字发送到标准输出之后。正如@abarnert 提到的,更糟糕​​的是,将数字转换为字符串以进行打印。这需要相当大的内存分配和处理能力。另一方面,第二个表达式只需要打印一个True。如果您分配给第一个表达式,您可以检查它:

 >>> a = 632382**518061

这样会抑制数字的输出。

【讨论】:

  • 我认为它更多的是格式化巨大的字符串并将其打印到输出。在我的机器上,编译乘法需要 1.68 秒,评估生成的编译文字需要 24.6 秒,str 它需要 28 秒,write 它只需 2 秒。在 Windows 上,编写或在 IDLE 中可能需要更多时间,但在体面的标准输出上,它不应该是主要瓶颈。
  • 28s 是 Python 2.7 的,和 3.4 非常接近,但是在 3.2 中,str 部分至少需要 6 分钟;我现在要去^C…
  • @abarnert 有道理,我可以在答案中添加它吗?
猜你喜欢
  • 2019-07-14
  • 1970-01-01
  • 1970-01-01
  • 2021-10-19
  • 2010-10-04
  • 2021-04-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多