python为何效率慢点?PHP跟Python的解释器都是C写的,PHP为什么能快点?

其实用python的人应该都是不关注它性能的人,毕竟写python确实很愉快
PHP的核心维护者花了很多的心血却提高底层的解释器效率,为什么Python的维护者不去呢?


程序员都喜欢用数据说话,这里我用的python版本是Python 3.6.2(64位),php版本是PHP 7.0.12(64位),node版本是v6.11.0(64位),Go 1.8.3(64位),C# 基于.Net 4.0,lua 5.1.4

对比

python

import time

calNum = 100000000

def test():
    sum = 0
    for x in range(1, calNum + 1):
        sum += x
    return sum


start = time.time()

test()

end = time.time()

print(end - start)

PHP

<?php

$calNum = 200000000;

function test() {
    $sum = 0;
    global $calNum;
    for ($i = 0; $i < $calNum; $i++) { 
        $sum += $i;
    }
    return $sum;
}

$start = time();

test();

$end = time();

echo ($end - $start);

nodeJS


let calNum = 200000000;

function test() {
    let sum = 0;
    for (var i = 0; i < calNum; i++) {
        sum += i;
    }
    return sum;
}

let start =  new Date().getTime();

test();

let end =  new Date().getTime();

console.log((end - start) / 1000);

Golang

package main

import (
    "fmt"
    "math"
    "time"
)

var calNum = 200000000

func test() int {
    sum := 0
    for i := 0; i < calNum; i++ {
        sum += i
    }
    return sum
}

func main() {
    start := time.Now().UnixNano()
    test()
    end := time.Now().UnixNano()
    fmt.Println(float64(end - start) / math.Pow(10, 9))
}

C#

 private static int calNum = 100000000;

        static int test()
        {
            int sum = 0;
            for (int i = 0; i < calNum; i++)
            {
                sum += i;
            }
            return sum;
        }

        static void Main(string[] args)
        {
            double start = ConvertDateTimeInt(DateTime.Now);
            test();
            double end = ConvertDateTimeInt(DateTime.Now);
            Console.WriteLine(end - start);
            Console.ReadLine();
        }

        /// <summary>
        /// DateTime时间格式转换为Unix时间戳格式
        /// </summary>
        /// <param name="time"> DateTime时间格式</param>
        /// <returns>Unix时间戳格式</returns>
        public static double ConvertDateTimeInt(DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            return (time - startTime).TotalSeconds;
        }

lua

calNum = 200000000


function test()
    local sum = 0
    for i=0,calNum - 1 do
        sum = i + sum
    end
    return sum
end

local start = os.time()
test()
local endTime = os.time()

print(endTime - start)

执行时间(1亿次,2亿次)

python

C:\Users\mh\Desktop>python cal.py
7.873001337051392

C:\Users\mh\Desktop>python cal.py
17.40298104286194

PHP

C:\Users\mh\Desktop>php cal.php
5
C:\Users\mh\Desktop>php cal.php
13

PHP 7.1(新下载的)

C:\Users\mh\Desktop>php cal.php
5
C:\Users\mh\Desktop>php cal.php
10

nodeJS

C:\Users\mh\Desktop>node cal.js
1.288

C:\Users\mh\Desktop>node cal.js
2.603

Golang

C:\Users\mh\Desktop>go run cal.go
0.0519903

C:\Users\mh\Desktop>go run cal.go
0.1080017

C#

0.685999155044556

1.52999567985535

lua(just for fun)

C:\Users\mh\Desktop>cal.lua
1

C:\Users\mh\Desktop>cal.lua
2

PHP还是比python快的,不过在脚本语言中node更快,Go挺快的

阅读 13k
6 个回答

python并不一定慢,许多Python的科学计算库通过用C来编写可以获得和全用c或者c++写的程序相同或者慢一到两倍的体验。

很多人认为他慢。他其实也确实慢。
一是GIL,其实GIL也只是CPython python解释器的特性,其主要是在多核机器上python无法获得多核所带来的性能优势。单核其实就差不多了。
楼下起风了不认可。首先大多数Python程序都是运行在CPython上的。无数用c语言为Python编写的好的库也是只能运行在cpyhon上的。所以GIL是大多数Python程序绕不开的东西。你说多进程可以解决。但是这也导致了一个问题就是进程间的数据共享问题。因为不在一个进程中共享内存空间这种高效的共享方式不能使用(当然GIL也是为了处理多线程共享内存所带来的风险而设置的。)这样你多线程间通信也会带来性能的损耗。当然你说可以通过多线程解决也没错,但是也不能说GIL不是导致大多数python慢的原因。

二是python是一门解释形语言,其是边运行边将python字节码编译成系统可以执行的可执行代码。这会带来一定的性能损耗,但是一个程序的快慢主要还是由其热点部分决定。通过将热点部分使用C语言编写,基本就可以获得很好的性能。
楼下起风了说python运行一次后编码就完成了。我想他可能没有理解解释型语言的编译。 Python在运行前编译好的文件是Python字节码。如果没有Python虚拟机是不能运行的。当在运行的时候Python虚拟机又吧Python字节码翻译成可以被CPU执行的二进制字节码。而像C语言这种是直接编译连接就可以生成直接被机器执行的二进制码。

其实对于大型应用影响其性能的首先是架构其次是程序编写逻辑然后是语言特性。大部分系统瓶颈都输数据库读取。加个redis缓存就可以获得不错的性能提升。 ins还不是用django撑起了全球最大图片分享网站。
手机打的错别字可能多一点??

import time

calNum = 100000000

def test():
    sum = 0
    for x in range(1, calNum + 1):
        sum += x
    return sum

def test1():
    sum = 0
    for x in xrange(1, calNum + 1):
        sum += x
    return sum

def test2(mylist):
    sum = 0
    for x in mylist:
        sum += x
    return sum

def test3():
    sum = 0
    i = 0
    while i < calNum:
        sum += i
        i += 1
    return sum

start = time.time()
test()
end = time.time()
print 'test time: {0}'.format(str(end-start))

start = time.time()
test1()
end = time.time()
print 'test1 time: {0}'.format(str(end-start))

mylist = range(1, calNum + 1)
start = time.time()
test2(mylist)
end = time.time()
print 'test2 time: {0}'.format(str(end-start))

start = time.time()
test3()
end = time.time()
print 'test3 time: {0}'.format(str(end-start))

四种不同的写法
test time: 7.10620498657
test1 time: 4.30882191658
test2 time: 4.70718193054
test3 time: 8.60779190063

四种不同的写法 获得时间也不同。 我之后再写一个链接了c语言库的实例补上。

看到其他答案都在为Python性能担忧,我这边也提供一个对性能提升的方法,题目的Python代码几乎不用变,只要加个 jit 修饰器即可,性能可秒杀其他语言,并且规模越大优势越明显:

import time
from numba import jit
calNum = 300000000

@jit
def test():
    sum = 0
    for x in range(1, calNum + 1):
        sum += x
    return sum


start = time.time()

test()

end = time.time()

print(end - start)

数字直接飙到3亿,运行一下看看,你一定会回来赞我的。

这个模块可以在 https://www.lfd.uci.edu/~gohl... 下载。

不清楚楼主说的效率是指哪方面的效率?

楼主有做过对比测试吗?

python3.6开始已经开始针对GIL的问题进行解决了,并准备摒弃这个东西了。可以拭目以待。

我对楼上的解释持怀疑态度。如果你觉得GIL是导致慢的原因,大可以用多进程替代,GIL的问题本质是导致多线程是分时复用而已(如果一个线程不间断地在 Python 2 中运行 1000 字节码指令,或者不间断地在 Python 3 运行15 毫秒,那么它便会放弃 GIL,而其他线程可以运行)。而且由于GIL本身,甚至可以导致多线程比单线程还慢。而且GIL是CPython的,大可用别的版本的Python实现。再者,并不是每个程序都有必要通过多线程去实现,而且事实上大多数人写的程序就是单线程的,所以这不能成为你的Python程序慢的借口。

Python说到底是一门高级语言,高级语言比低级语言慢是很正常的事情,你去看看leetcode里面解题时间vs不同语言的柱状图就知道差距了,反正不是楼上说的一两倍。再说上面提到的边运行边编译字节码的问题,除了主脚本以外,如果别的py文件没做改动,且运行的python解释器版本相同,它是不会重新编译的,而且python添加了编译优化选项,所以我觉得这也不是个很好的理由。比如你写了一个for循环,循环上万次,里面就只是数据结构动态重绑定之类的简单操作或者就是简单的加法(没有类型的加法),那你能说是编译,加载,连接是主要导致慢的原因嘛?再说很多比Python快的面向对象的语言也会用到虚拟机,总不能一股脑全部赖在这个中间步骤上。

至于为什么慢,又回到高级语言的话题上,python是1.高级的 2.动态的戳这里
楼上提到主要解决热点问题是一致推荐的,一般prototype用python编写,较慢的代码会用低级语言重构。

当我们一定要讨论某种语言快慢的时候,是不是应该剖析语言本身的特性和准则,而并不是针对某个特定实现版本,虽然即使这个版本是大多数人用的。

只是本人基于自己的理解YY的,大家讨论哈~

PHP的核心维护者花了很多的心血却提高底层的解释器效率,为什么Python的维护者不去呢?

可能是因为 php 以前太慢了呗。

韩天峰大大写到:

benchmarksgame 上面的测试基本上都是密集计算的。PHP 和 Python(CPython) 目前都没有 JIT,PHP
能胜出只能说明底层 VM 性能比 Python 的要好。实际上 PHP 语言官方开发组从 5.4 时代就一直在优化 VM 的性能。PHP7版本对底层的数据结构进行了很大的改造,相比 5.6 提升了 1 倍以上的性能。而 Python 3 相比 Python 2性能上反而是在退步。 密集计算场景,静态语言和 有 JIT 的动态语言 会有很大的优势。可以看到 Node.js(基于 V8 引擎)的测试成绩远超 PHP 和 Python 。前者的计算指令是直接作为 CPU 指令执行的,后者计算实际上是 VM
上的高级指令,实现原理上有很大差异。不过,各位 PHPer 也别灰心,PHP 官方开发组已经在开发 JIT 特性了,也许下个版本 PHP就会携带 JIT ,到时在密集计算场景下将会和 Node.js 在同一数量级。另外再说句,PHP、Python、Node.js都是写应用软件的,语言的计算性能没那么重要。你的程序如果对性能敏感,C/C++/GO/Rust 这些静态编程语言才是最好的选择。

同为动态语言,python的性能为何只有PHP的五分之一?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏