其實(shí)用python的人應(yīng)該都是不關(guān)注它性能的人,畢竟寫python確實(shí)很愉快
PHP的核心維護(hù)者花了很多的心血卻提高底層的解釋器效率,為什么Python的維護(hù)者不去呢?
程序員都喜歡用數(shù)據(jù)說話,這里我用的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
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
$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);
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);
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))
}
#
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時(shí)間格式轉(zhuǎn)換為Unix時(shí)間戳格式
/// </summary>
/// <param name="time"> DateTime時(shí)間格式</param>
/// <returns>Unix時(shí)間戳格式</returns>
public static double ConvertDateTimeInt(DateTime time)
{
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
return (time - startTime).TotalSeconds;
}
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)
C:\Users\mh\Desktop>python cal.py
7.873001337051392
C:\Users\mh\Desktop>python cal.py
17.40298104286194
C:\Users\mh\Desktop>php cal.php
5
C:\Users\mh\Desktop>php cal.php
13
C:\Users\mh\Desktop>php cal.php
5
C:\Users\mh\Desktop>php cal.php
10
C:\Users\mh\Desktop>node cal.js
1.288
C:\Users\mh\Desktop>node cal.js
2.603
C:\Users\mh\Desktop>go run cal.go
0.0519903
C:\Users\mh\Desktop>go run cal.go
0.1080017
#
0.685999155044556
1.52999567985535
C:\Users\mh\Desktop>cal.lua
1
C:\Users\mh\Desktop>cal.lua
2
PHP還是比python快的,不過在腳本語言中node更快,Go挺快的
python并不一定慢,許多Python的科學(xué)計(jì)算庫通過用C來編寫可以獲得和全用c或者c++寫的程序相同或者慢一到兩倍的體驗(yàn)。
很多人認(rèn)為他慢。他其實(shí)也確實(shí)慢。
一是GIL,其實(shí)GIL也只是CPython python解釋器的特性,其主要是在多核機(jī)器上python無法獲得多核所帶來的性能優(yōu)勢。單核其實(shí)就差不多了。
樓下起風(fēng)了不認(rèn)可。首先大多數(shù)Python程序都是運(yùn)行在CPython上的。無數(shù)用c語言為Python編寫的好的庫也是只能運(yùn)行在cpyhon上的。所以GIL是大多數(shù)Python程序繞不開的東西。你說多進(jìn)程可以解決。但是這也導(dǎo)致了一個問題就是進(jìn)程間的數(shù)據(jù)共享問題。因?yàn)椴辉谝粋€進(jìn)程中共享內(nèi)存空間這種高效的共享方式不能使用(當(dāng)然GIL也是為了處理多線程共享內(nèi)存所帶來的風(fēng)險(xiǎn)而設(shè)置的。)這樣你多線程間通信也會帶來性能的損耗。當(dāng)然你說可以通過多線程解決也沒錯,但是也不能說GIL不是導(dǎo)致大多數(shù)python慢的原因。
二是python是一門解釋形語言,其是邊運(yùn)行邊將python字節(jié)碼編譯成系統(tǒng)可以執(zhí)行的可執(zhí)行代碼。這會帶來一定的性能損耗,但是一個程序的快慢主要還是由其熱點(diǎn)部分決定。通過將熱點(diǎn)部分使用C語言編寫,基本就可以獲得很好的性能。
樓下起風(fēng)了說python運(yùn)行一次后編碼就完成了。我想他可能沒有理解解釋型語言的編譯。 Python在運(yùn)行前編譯好的文件是Python字節(jié)碼。如果沒有Python虛擬機(jī)是不能運(yùn)行的。當(dāng)在運(yùn)行的時(shí)候Python虛擬機(jī)又吧Python字節(jié)碼翻譯成可以被CPU執(zhí)行的二進(jìn)制字節(jié)碼。而像C語言這種是直接編譯連接就可以生成直接被機(jī)器執(zhí)行的二進(jìn)制碼。
其實(shí)對于大型應(yīng)用影響其性能的首先是架構(gòu)其次是程序編寫邏輯然后是語言特性。大部分系統(tǒng)瓶頸都輸數(shù)據(jù)庫讀取。加個redis緩存就可以獲得不錯的性能提升。 ins還不是用django撐起了全球最大圖片分享網(wǎng)站。
手機(jī)打的錯別字可能多一點(diǎn)??
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
四種不同的寫法 獲得時(shí)間也不同。 我之后再寫一個鏈接了c語言庫的實(shí)例補(bǔ)上。
我對樓上的解釋持懷疑態(tài)度。如果你覺得GIL
是導(dǎo)致慢的原因,大可以用多進(jìn)程替代,GIL
的問題本質(zhì)是導(dǎo)致多線程是分時(shí)復(fù)用而已(如果一個線程不間斷地在 Python 2 中運(yùn)行 1000 字節(jié)碼指令,或者不間斷地在 Python 3 運(yùn)行15 毫秒,那么它便會放棄 GIL,而其他線程可以運(yùn)行)
。而且由于GIL本身,甚至可以導(dǎo)致多線程比單線程還慢。而且GIL是CPython的,大可用別的版本的Python實(shí)現(xiàn)。再者,并不是每個程序都有必要通過多線程去實(shí)現(xiàn),而且事實(shí)上大多數(shù)人寫的程序就是單線程的,所以這不能成為你的Python程序慢的借口。
Python說到底是一門高級語言,高級語言比低級語言慢是很正常的事情,你去看看leetcode
里面解題時(shí)間vs不同語言的柱狀圖
就知道差距了,反正不是樓上說的一兩倍。再說上面提到的邊運(yùn)行邊編譯字節(jié)碼的問題,除了主腳本以外,如果別的py文件沒做改動,且運(yùn)行的python解釋器版本相同,它是不會重新編譯的,而且python添加了編譯優(yōu)化選項(xiàng),所以我覺得這也不是個很好的理由。比如你寫了一個for循環(huán),循環(huán)上萬次,里面就只是數(shù)據(jù)結(jié)構(gòu)動態(tài)重綁定之類的簡單操作或者就是簡單的加法(沒有類型的加法),那你能說是編譯,加載,連接是主要導(dǎo)致慢的原因嘛?再說很多比Python快的面向?qū)ο蟮恼Z言也會用到虛擬機(jī),總不能一股腦全部賴在這個中間步驟上。
至于為什么慢,又回到高級語言的話題上,python是1.高級的 2.動態(tài)的
,戳這里
樓上提到主要解決熱點(diǎn)問題是一致推薦的,一般prototype用python編寫,較慢的代碼會用低級語言重構(gòu)。
當(dāng)我們一定要討論某種語言快慢的時(shí)候,是不是應(yīng)該剖析語言本身的特性和準(zhǔn)則,而并不是針對某個特定實(shí)現(xiàn)版本,雖然即使這個版本是大多數(shù)人用的。
只是本人基于自己的理解YY的,大家討論哈~
看到其他答案都在為Python性能擔(dān)憂,我這邊也提供一個對性能提升的方法,題目的Python代碼幾乎不用變,只要加個 jit
修飾器即可,性能可秒殺其他語言,并且規(guī)模越大優(yōu)勢越明顯:
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)
數(shù)字直接飆到3億,運(yùn)行一下看看,你一定會回來贊我的。
這個模塊可以在 https://www.lfd.uci.edu/~gohl... 下載。
韓天峰大大寫到:
benchmarksgame 上面的測試基本上都是密集計(jì)算的。PHP 和 Python(CPython) 目前都沒有 JIT,PHP
能勝出只能說明底層 VM 性能比 Python 的要好。實(shí)際上 PHP 語言官方開發(fā)組從 5.4 時(shí)代就一直在優(yōu)化 VM 的性能。PHP7版本對底層的數(shù)據(jù)結(jié)構(gòu)進(jìn)行了很大的改造,相比 5.6 提升了 1 倍以上的性能。而 Python 3 相比 Python 2性能上反而是在退步。 密集計(jì)算場景,靜態(tài)語言和 有 JIT 的動態(tài)語言 會有很大的優(yōu)勢??梢钥吹?Node.js(基于 V8 引擎)的測試成績遠(yuǎn)超 PHP 和 Python 。前者的計(jì)算指令是直接作為 CPU 指令執(zhí)行的,后者計(jì)算實(shí)際上是 VM
上的高級指令,實(shí)現(xiàn)原理上有很大差異。不過,各位 PHPer 也別灰心,PHP 官方開發(fā)組已經(jīng)在開發(fā) JIT 特性了,也許下個版本 PHP就會攜帶 JIT ,到時(shí)在密集計(jì)算場景下將會和 Node.js 在同一數(shù)量級。另外再說句,PHP、Python、Node.js都是寫應(yīng)用軟件的,語言的計(jì)算性能沒那么重要。你的程序如果對性能敏感,C/C++/GO/Rust 這些靜態(tài)編程語言才是最好的選擇。
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
北大青鳥中博軟件學(xué)院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學(xué)院和江蘇省首批服務(wù)外包人才培訓(xùn)基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團(tuán)創(chuàng)建于1999年,經(jīng)過二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術(shù)與教育服務(wù)機(jī)構(gòu),發(fā)展為教育服務(wù)業(yè)的綜合性企業(yè)集團(tuán),成為集合面授教學(xué)培訓(xùn)、網(wǎng)
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。