【问题标题】:Why is this code faster with Python than with C++? [closed]为什么这段代码用 Python 比用 C++ 快? [关闭]
【发布时间】:2021-03-01 11:59:12
【问题描述】:

我写了一个简单的代码来比较 Python 和 C++ 的速度。这是 Python 代码:

def count_permutations(N:int)->int:
    count=0
    for p in itertools.permutations(range(1,N+1)):
        count += 1
    return count

这里是 C++ 代码:

int count_permutations(int N) {
    vector<int> v(N);
    iota(v.begin(), v.end(), 1); // fill the vector with 1,...,N
    int count=0;
    do {
        ++count;
    } while ( next_permutation(v.begin(),v.end()) );
    return count;
}

当我在 Ubuntu 上使用 Python 3.8.5 运行时,我得到:

Permutations of 1..11:
  39916800 permutations calculated in 3.31172251701355 seconds
Permutations of 1..12:
  479001600 permutations calculated in 40.63520336151123 seconds

当我在同一个 Ubuntu 上使用 C++ (clang++-9) 运行时,没有优化,我得到:

Permutations of 1..11:
  39916800 permutations calculated in 5 seconds
Permutations of 1..12:
  479001600 permutations calculated in 57 seconds

我觉得这很奇怪,因为在benchmarks 网站上,C++ 总是比 Python 快。

有没有可能最近版本的 Python 变得如此之快以至于它们现在比 C++ 并行更快?

【问题讨论】:

  • 你打开编译器优化了吗?这段代码 57 秒看起来太多了,是调试版本吗?
  • @largest_prime_is_463035818 与优化 C++ 确实要快得多。
  • @Caleth 如果不转换为列表就无法工作,对吧?
  • 大部分性能来自编译器优化,如果不使用它们,就没有理由期望 C++ 代码性能更好

标签: python c++ performance


【解决方案1】:

理论 C++ 性能只能被较低级别的语言超越,在这种情况下是原始 asm/机器代码。这当然高度依赖于具体的代码。但是如果不完全重写和重新设计解释器,CPython 将永远无法获得这种水平的性能。有一些设计选择(例如 gil、no jit 等)只会阻止它表现良好。然而,其他一些 Python 实现,例如PyPy 的性能可能非常好,有时甚至可以与低级语言相媲美。

如果您的 C++ 代码的性能与 Python 代码相似或更差,那么您应该检查以下内容:

  1. 您应该在编译 C++ 时进行优化(从 cmets 判断这是您的问题)。
  2. 两种语言的代码应该是相同的。不难忽略影响性能的细微差异。
  3. 代码是等效的,但您使用更差的 C++ 算法/实现。请注意,标准 C++ 库不能保证是最快的。它通常提供大 O 保证,这是不一样的。某些功能的默认 Python 实现实际上可能比默认 C++ 实现更快,尽管可能性不大。
  4. 您的 Python 代码已经高度优化,并且实际上可以通过 C/C++ 插件运行(这就是为什么例如 ML 与 Python 是有意义的)。

【讨论】:

  • 它只是措辞,但“理论 C++ 性能只能被较低级别的语言超越”似乎与“理论上可能会发生某些功能的默认 Python 实现实际上比默认 C++ 更快实施”
  • @largest_prime_is_463035818 我不这么认为,也许“理论上”的词选择不当(删除)。第二个陈述只是“默认的 C++ 实现可能不是最优的”。尽管理论上有一种方法可以使它变得如此出色(当然是在 C++ 内部),以至于没有其他(更高级别的)语言会超过性能。人们经常忘记 std 只是一个由某些人编写的库。没有什么神奇的规则说它是 C++ 的最佳库。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-24
  • 1970-01-01
  • 2011-05-27
  • 2016-01-30
  • 2015-03-26
  • 2017-08-22
相关资源
最近更新 更多