【问题标题】:How fast is Python? [closed]Python有多快? [关闭]
【发布时间】:2009-11-06 08:27:42
【问题描述】:

我是一名 Java 程序员,如果有一点我不喜欢它,那就是速度。 Java 看起来真的很慢,但是到目前为止我编写的许多 Python 脚本程序似乎真的很快。

所以我只是想知道 Python 是否比 Java 或 C# 快,以及它与 C/C++ 相比如何(我认为它会慢)?

【问题讨论】:

  • 一根绳子很长。
  • Java- 100 英里/小时,Python 200 英里/小时,C/C++ 1000 英里/小时
  • 西努斯,你怎么能这么说?
  • @Geo:只是一个疯狂的猜测......这取决于路况、机器调谐、燃料和许多其他因素......
  • 蟒蛇的速度大约是……等等,我们说的是欧洲蟒蛇还是非洲蟒蛇?

标签: python performance


【解决方案1】:

就原始性能而言,Python 肯定比 Java、C# 和 C/C++ 慢。但是,对于用户/观察者来说,还有其他一些事情很重要,例如总内存使用量、初始启动时间等。对于大多数事情,Python 足够快 ;)

This site 让您可以比较不同的编程语言。它使用简单的条形图来显示速度、内存使用情况等。

如果您有兴趣,可以看看备受期待的 Unladen Swallow 项目,该项目正在努力将 Python 的性能提高到 CPython 的五倍(!)

【讨论】:

  • 我喜欢你所说的“足够快”。这当然也是我使用 Python 的经验。
  • +1 表示“足够快” - 人们往往会花太多时间谈论性能
  • “足够快”对于所有不需要快速的东西 :-)
  • @igouy 然后你在 Cython 中编写需要快速的部分,或者在适当的情况下使用 Numpy。
  • @igouy:我想当你培养一个经验不足的开发人员团队时,他们可以用 C++ 编写代码“足够快”,用于任何不需要“快速”编写的项目。我认为 lemonad 试图说明的一点是,在实际受限的工作环境中,语言的性能不一定是“王者”。
【解决方案2】:

这完全取决于用例。对于长时间运行的应用程序(如服务器),Java 已被证明非常快——甚至比 C 还要快。这是可能的,因为 JVM 可能会将热字节码编译为机器码。在这样做的同时,它可以充分利用 CPU 的每一个特性。对于 C 语言来说,这通常是不可能的,至少在您离开实验室环境后:假设向您的客户分发了十几个优化的构建 - 这根本行不通。

但回到你的问题:这真的取决于。例如。如果启动时间是一个问题(例如对于服务器应用程序来说不是问题),Java 可能不是最佳选择。这也可能取决于您的热门代码区域在哪里:如果它们位于本机库中,并带有一些 Python 代码将它们简单地粘合在一起,那么您也可以使用 Python 获得类似 C 的性能。

通常情况下,脚本语言往往会比较慢 - 至少在大多数情况下是这样。

【讨论】:

    【解决方案3】:

    如果您想要 Python 的速度,尤其是对于复杂算法,Psyco 通常会有所帮助。从他们的网页:

    将 Psyco 视为一种 即时(JIT)编译器,一点 有点像其他人的存在 发出机器代码的语言 苍蝇而不是解释你的 Python程序一步一步来。这 与传统的区别 JIT 编译器的方法是 Psyco 编写了几个版本的 相同的块(一个块有点像 功能),这是由优化 专门用于某些类型的 变量(“种类”可以表示类型, 但它更通用)。结果是 你未经修改的 Python 程序 跑得更快。

    2 倍到 100 倍的加速,通常是 4 倍, 使用未经修改的 Python 解释器 和未经修改的源代码,只是一个 可动态加载的 C 扩展 模块。

    奇怪的是,上面的链接中没有提到它。

    【讨论】:

    • 他们忘了说有时会减速 xD
    • 很遗憾,Psycho 已经好几年没有开发出来了,而且永远不会在 64 位平台上工作。
    • @thrope:那是因为 psyco 被 pypy 弃用了,当 x86 JIT 后端最终实现 int 和 floats 时,它的性能已经超过了 psyco。 pypy 是一个 JIT 生成器。
    • Psyco 将为您提供更多类似 Java 的性能。您将获得更慢的启动时间和更高的内存使用率,以换取更快的算法。
    【解决方案4】:

    这是另一个看起来更完整的stackoverflow question:您还可以查看computer language shootout

    【讨论】:

    • 糟糕。感谢您提供替代链接。
    • 然而,psyco,Python JIT 编译器在枪战中是不允许的......
    • pysco 出现在 2008 年,这里是 InternetArchive 链接,您为什么不使用基准测试游戏提供的 Python 脚本来发布您最喜欢的语言实现的测量值? web.archive.org/web/20080606020118/http://…
    • @igouy 请不要更改答案内容
    • 410 不见了。 @AK_ 请更正网址。
    【解决方案5】:

    很难对两种语言的运行速度进行真正客观和普遍的比较。在比较任意两种语言 X 和 Y 时,人们经常会发现 X 在某些方面比 Y 快,而在其他方面则较慢。对我来说,这使得在线提供的任何基准/比较基本上毫无用处。最好的方法是自己测试一下,看看每种语言对于你正在做的工作有多快。

    话虽如此,在测试 Java 和 Python 等语言时应该记住一些事情。这些语言中的代码通常可以通过使用更适合该语言的结构来显着加快速度(例如 Python 中的列表推导,或使用 char[] 和 StringBuilder 进行 Java 中的某些字符串操作)。而且,对于 Python 来说,使用 psyco 可以大大提高程序的速度。然后是使用适当的数据结构并密切关注代码的运行时复杂性的整个问题。

    【讨论】:

    【解决方案6】:

    我认为 Keyle 的回答(以及其他人)带出了一个基本观点:很大程度上取决于你做事的方式。该链接为 C++ 提供了两个答案,但我很难相信任何人通常会编写与任何一个都非常相似的 C++。我的第一次尝试看起来像这样:

    #include <iostream>
    #include <vector>
    #include <time.h>
    
    class person { 
        int count_;
        static int current_;
    public:
        person() : count_(++current_) {}
        int count() { return count_; }
    };
    int person::current_ = 0;
    typedef std::vector<person> plist;
    class chain {
        plist people_;
        void check_wrap(std::vector<person>::iterator &p) {
            if (p==people_.end())
                p = people_.begin();
        }
        void advance(std::vector<person>::iterator &p, int places) {
            for (int i=0; i<places; i++)
                check_wrap(++p);
        }
    public:
        chain(int length) : people_(length) {}
        person *kill(int n) { 
            plist::iterator current = people_.begin();
            while (people_.size()>1) {
                advance(current, n);
                current = people_.erase(current);
                check_wrap(current);
            }
            return &(*current);
        }
    };
    int main() {
        const int ITER = 1000000;  
        clock_t start = clock();
        for(int i = 0 ; i <ITER; i++) {
            chain c(40);
            c.kill(3);  
        }
        clock_t end = clock();
        std::cout << "Time per iterator: " << (((end - start) /(double)CLOCKS_PER_SEC/ITER)*1000000 << " microseconds.\n";
        return 0;
    }
    

    (为了便于携带,我使用了 clock() 而不是 gettimeofday,但任何想要的人都可以轻松地将它改回来)。

    这有几点让我觉得很有趣。首先,代码缩短了很多——事实上,与所示的最短代码一样具有竞争力。其次,代码变得更快了——可能比 C++ 中特别优化的版本更快。

    最后,至少在我看来,代码似乎变得更容易阅读和理解了。对我来说,他的“shout()”似乎很令人困惑,就像让“Person”真正成为 Person 对象链表中的一个节点一样,Chain 处理一些链表管理,但“Person”也做链接-将事物与“人”事物一起列出。

    这并不一定(或直接)告诉我们 Python 的速度,但我认为它可以让您了解您可以在网络上找到的许多基准测试的质量。编写几乎任何有意义且准确的基准非常困难 - 尝试跨语言进行比较是其中最困难的之一。

    【讨论】:

    • 确实如此,尽管您的算法可能已损坏。就 Java 和 C++ 的比较而言,它可能只是表明小对象分配/释放不是 C++ 的强项。使用向量(即使为每次迭代重新分配)和擦除的简单方法和缩短约 3-4 倍的方法表明,C++ 代码可以轻松地提高约 5-6 倍,而无需任何花哨的东西。我怀疑基准测试对于其他语言同样不是最佳的,对于 Java 也是如此。
    • 这对于 Java 可能不是最理想的,但对于 Java,它可能并没有那么大的区别。此代码的一部分已损坏(我忘记了向量填充单个对象的副本,而不是独立创建每个对象,因此它们都得到了 1 的 count_。除此之外,我相信它可以正常工作。跨度>
    【解决方案7】:

    这是一个您无法正确回答的问题,因为这完全取决于何时必须快速。 Java 适用于大型服务器,但当您必须多次重新编译和测试代码时(编译速度非常慢),这很糟糕。 Python 甚至不需要编译来测试!

    在生产环境中,说 Java 比 C 快是完全愚蠢的......就像说 C 比汇编快。

    无论如何不可能准确回答:这完全取决于您想要/需要什么。

    【讨论】:

    • 我不同意您关于 Java 代码难以测试的说法。增量编译和热代码替换使测试 Java 非常快——我通常不会注意到它。此外,说 Java 不能比 C 快一点也不傻。JVM 会尝试将热代码区编译为机器码。该机器代码将针对运行它的机器进行大量优化。对于 C,您可以在编译时执行此操作 - 但您不能总是预测代码将在哪个机器上运行,因此它可能会针对 i386 进行编译以满足大多数客户的需求。
    • 我同意你对 Java 的看法。但是对于 C 来说,它总是与谁编译它有关。如果你制作了一个好的makefile,并且你开发得当,那么相同的编译Java代码根本不可能更快。一点也不。唯一可能的情况是,当您拥有使用 Java 开发并使用错误的 makefile 编写错误代码并比较速度的同一开发人员时。这完全取决于开发人员的技能。您唯一可以说的是“如果开发人员不懂 C,Java 有时比 C 更快”!。但是 C 的速度总是与 Java 一样快。
    • 出于实际原因,许多 C/C++ 程序只提供一个可执行文件(或尽可能少的可执行文件,例如一个用于 Mac,一个用于 Windows)。鉴于此,一个可执行文件可能会尽可能地简单,以便程序可以在尽可能多的机器上运行。这意味着,如果您有一个新的 CPU,其中包含一些可用于加速执行的漂亮新指令,那么大多数 C/C++ 程序可能不会使用该漂亮的新指令。 Java 程序,OTOH,只要你的 Java 运行时的 JIT 知道它就可以利用它。
    【解决方案8】:

    对于 Python,速度也取决于解释器的实现...我看到 pypy 通常比 cpython 快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-21
      • 2011-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-13
      • 1970-01-01
      相关资源
      最近更新 更多