【问题标题】:PyPy vs. CPython 3.8 - Difference in "number of iterations" with the same code?PyPy vs. CPython 3.8 - 相同代码的“迭代次数”差异?
【发布时间】:2021-01-20 20:22:59
【问题描述】:

我在修改用 Python 编写的数独求解算法时偶然发现了一个有趣的现象。

我正在计算回溯算法中的迭代次数并将数字保存在日志文件中。 (该算法似乎是完全确定性的,因此我对突然增加迭代次数以获得相同输出很感兴趣。)

现在有趣的部分是:

当我尝试使用 PyPy (3.7-v7.3.3-win32) 而不是 Python 3.8 (64bit) 运行相同的代码时,使用 PyPy 运行时的迭代次数从 362073 增加到 629505 时大约翻了一番CPython。

我的问题是:有谁知道为什么迭代次数会有这种差异?

日志:

Iterations: 629505, Time Taken: 0.8950409889221191, File: ./sudokus/9x9.csv  -- PyPy 3.7
Iterations: 629505, Time Taken: 0.895305871963501, File: ./sudokus/9x9.csv  -- PyPy 3.7
Iterations: 362073, Time Taken: 2.1060104370117188, File: ./sudokus/9x9.csv -- Python 3.8
Iterations: 362073, Time Taken: 2.1779544353485107, File: ./sudokus/9x9.csv -- Python 3.8

对于另一个数独文件,差异也在那里,但可以忽略不计:

Iterations: 19443164, Time Taken: 106.15500068664551, File: test_0.csv -- Python 3.8
Iterations: 19443259, Time Taken: 13.188998937606812, File: ./sudokus/test_0.csv  -- PyPy 3.7
Iterations: 19443259, Time Taken: 13.118957042694092, File: ./sudokus/test_0.csv  -- PyPy 3.7

我的代码是这样的: https://github.com/kasztp/kiwi.com-sudoku-solver/blob/OCR/sudoku_solver.py

【问题讨论】:

  • 代码需要直接在此处发布,最好简化为minimal reproducible example,以显示重现问题的窄示例。
  • 代码在问题中,而不是在外部链接中。

标签: python algorithm loops sudoku pypy


【解决方案1】:

我认为你在第 117 行枚举集合。这个顺序在 CPython 中是未指定的,即任意的。在 PyPy 中,您将获得将项目放入集合中的顺序。

【讨论】:

    【解决方案2】:

    我在两个并发调试会话中逐步检查了您的代码,每个解释器一个。 self.mask 中的 sets 在两个解释器之间看起来不一样——它们包含相同的值,但顺序不同。即使在solve 的第二次递归(当self.iterations 变为2 时),由于这种差异,执行流程也会发散。我不知道这是否是您所看到的差异的确切原因,但我猜这与 sets 在一种实现中保证插入顺序有关,而不是在另一种实现中。

    【讨论】:

    • 谢谢,有道理。在这种情况下,如果一个解释器中的顺序是准随机的,那么我不应该在每次运行时看到迭代次数的一些变化吗? (这里两个解释器的迭代次数是一致的,只是它们之间的数字不同。)
    • @kasztp 当一个实现说它不保证集合的插入顺序时,这就是它的全部含义。这并不意味着集合中的项目将随机排序。它们将以某种任意但确定性的方式排序。不一定按插入顺序,也不一定按标准指定的方式。实现可以随意建立集合的顺序。
    • 谢谢,这澄清了!
    猜你喜欢
    • 2018-03-02
    • 2011-04-29
    • 2019-01-26
    • 1970-01-01
    • 2012-04-28
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多