成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為啥Python運行速度這么慢 ?

新聞 后端
近來 Python 可謂人氣驟升。這門編程語言用于開發運維(DevOps)、數據科學、網站開發和安全。

 

作者:Anthony Shaw 是 Python 軟件基金會成員和 Apache 基金會成員。

  近來 Python 可謂人氣驟升。這門編程語言用于開發運維(DevOps)、數據科學、網站開發和安全。

  然而,它沒有因速度而贏得任何獎牌。

  Java 在速度方面與C、C++、C#或 Python 相比如何?答案很大程度上取決于你運行的應用程序的類型。沒有哪個基準測試程序盡善盡美,不過 The Computer Language Benchmarks Game(計算機語言基準測試游戲)是個不錯的起點。

  十多年來,我一直提到計算機語言基準測試游戲;與 Java、C#、Go、JavaScript 和 C++ 等其他語言相比,Python 是速度最慢的語言之一。除了 JavaScript 等解釋語言外,這還包括 JIT(C#和 Java)以及 AOT(C和C++)編譯器。

  注意:我說“Python”時,其實指這種語言的參考實現:CPython。我會在本文中提到其他運行時環境。

  我想回答這個問題:Python 運行完成類似的應用程序比另一種語言慢 2 倍至 10 倍時,為什么它這么慢,我們能不能讓它更快些?

  下面是幾種常見的說法:

  • “它是 GIL(全局解釋器鎖)”

  • “這是由于它是解釋的,而非編譯”

  • “這是由于它是一種動態類型語言”

  那么,到底上述哪個原因對性能帶來的影響***?

  “它是 GIL”

  現代計算機搭載擁有多個內核的 CPU,有時搭載多個處理器。為了利用所有這些額外的處理能力,操作系統定義了一種名為線程的低級結構:一個進程(比如 Chrome 瀏覽器)可能生成多個線程,并擁有針對內部系統的指令。這樣一來,如果某個進程特別耗費 CPU 資源,該負載可以在諸多核心之間分擔,這實際上讓大多數應用程序更快地完成任務。

  我在寫這篇文章時,我的 Chrome 瀏覽器有 44 個線程開著。請記住這點:線程的結構和 API 在基于 POSIX 的操作系統(比如 Mac OS 和 Linux)與 Windows OS 之間是不同的。操作系統還處理線程的調度。

  如果你之前沒有從事過多線程編程,需要盡快熟悉的一個概念就是鎖(lock)。與單線程進程不同,當你需要確保改變內存中的變量時,多個線程并不同時試圖訪問/改變同樣的內存地址。

  CPython 創建變量時,它會分配內存,然后計算該變量的引用有多少,這個概念名為引用計數(reference counting)。如果引用數為0,那么它從系統釋放這部分內存。這就是為什么在某個代碼段(比如 for 循環的范圍)內創建一個“臨時”變量不會搞砸應用程序的內存消耗。

  當變量在多個線程內共享時,就出現了這個難題:CPython 如何鎖定引用計數。有一個“全局解釋器鎖”,它小心地控制線程執行。解釋器一次只能執行一個操作,無論它有多少線程。

  這對 Python 應用程序的性能來說意味著什么?

  如果你有單線程、單個解釋器的應用程序,這對速度不會有影響。刪除 GIL 根本不會影響你代碼的性能。

  如果你想通過使用線程機制在單個解釋器(Python 進程)內實現并發功能,而且線程是 IO 密集型(比如網絡 IO 或磁盤 IO),你會看到 GIL 爭奪的后果。

  上圖來自大衛·比茲利(David Beazley)撰寫的《GIL 可視化》文章:

  http://dabeaz.blogspot.com/2010/01/python-gil-visualized.html

  如果你有 Web 應用程序(比如 Django),又在使用 WSGI,那么針對 Web 應用程序的每個請求都是一個單獨的 Python 解釋器,所以每個請求只有一個鎖。由于 Python 解釋器啟動緩慢,一些 WSGI 實現擁有“守護進程模式”,這可以讓一個或多個 Python 進程為你保持活躍狀態。

  其他 Python 運行時環境怎么樣?

  PyPy 有一個 GIL,它通常比 CPython 快 3 倍。

  Jython 之所以沒有 GIL,是由于 Jython 中的 Python 線程由 Java 線程表示,受益于 JVM 內存管理系統。

  JavaScript 如何執行此任務?  

  好吧,首先所有 Javascript 引擎都使用標記-清除(mark-and-sweep)垃圾收集機制。如上所述,GIL 的主要需求是 CPython 的內存管理算法。

  JavaScript 沒有 GIL,但它也是單線程的,所以它不需要內存管理算法。JavaScript 的事件循環和承諾回調(Promise/Callback)模式是實現異步編程以代替并發的方法。Python 與 asyncio 事件循環有相似之處。

  “這是由于它一種解釋語言”  

  我常聽到這個觀點,但覺得這過于簡化了 CPython 的實際工作方式。如果你在終端上編寫了 python myscript.py,那么 CPython 會啟動讀取、分析、解析、編譯、解釋和執行代碼的一長串操作。

  如果你對這個過程的機理頗感興趣,我之前寫過一篇文章:《6 分鐘內修改 Python 語言》(https://hackernoon.com/modifying-the-python-language-in-7-minutes-b94b0a99ce14)。

  這個過程的一個重要節點是創建 .pyc 文件;在編譯階段,字節碼序列寫入到 Python 3 中__pycache__/里面的一個文件或 Python 2 中的同一個目錄。這不僅適用于你的腳本,還適用于導入的所有代碼,包括第三方模塊。

  所以在大部分時間(除非你編寫的是只運行一次的代碼?),Python 解釋字節碼,并在本地執行。相比之下 Java 和C#.NET:

  Java 編譯成一種“中間語言”,Java 虛擬機讀取字節碼,并即時編譯成機器碼。.NET CIL 也一樣,.NET 公共語言運行時環境(CLR)使用即時編譯,將編譯后代碼編譯成機器碼。

  那么,既然都使用虛擬機和某種字節碼,為什么 Python 在基準測試中比 Java 和 C# 都要慢得多呢?首先,.NET 和 Java 是 JIT 編譯型的。

  JIT 或即時編譯需要一種中間語言,以便將代碼拆分成塊(或幀)。提前(AOT)編譯器旨在確保 CPU 在任何交互發生之前能理解每一行代碼。

  JIT 本身不會使執行變得更快,因為它仍然執行相同的字節碼序列。然而,JIT 讓代碼在運行時能夠加以優化。一個好的 JIT 優化器會看到應用程序的哪些部分在頻繁執行,這些代碼稱之為“熱點代碼”(hot spot)。然后,它會對這些代碼進行優化,其辦法是把它們換成更高效的版本。

  這就意味著當你的應用程序一次又一次地執行相同的操作時,運行速度可以顯著加快。另外記住一點:Java 和 C# 是強類型語言,因此優化器可以對代碼做出多得多的假設。

  PyPy 有 JIT,如上所述,其速度比 CPython 快得多。這篇性能基準測試文章作了更詳細的介紹:《哪個 Python 版本的速度最快?》(https://hackernoon.com/which-is-the-fastest-version-of-python-2ae7c61a6b2b)。

  那么,CPython 為什么不使用 JIT 呢?

  JIT 存在幾個缺點:缺點之一是啟動時間。CPython 的啟動時間已經比較慢了,PyPy 的啟動時間比 CPython 還要慢 2 倍至 3 倍。眾所周知,Java 虛擬機的啟動速度很慢。.NET CLR 通過系統開啟時啟動解決了這個問題,但 CLR 的開發人員還開發了操作系統,CLR 在它上面運行。

  如果你有一個 Python 進程長時間運行,代碼因含有“熱點代碼”而可以優化,那么 JIT 大有意義。

  然而,CPython 是一種通用實現。所以,如果你在使用 Python 開發命令行應用程序,每次調用 CLI 都得等待 JIT 啟動會慢得要命。

  CPython 不得不試圖滿足盡可能多的用例(use case)。之前有人試過將 JIT 插入到 CPython 中,但這個項目基本上擱淺了。

  如果你想獲得 JIT 的好處,又有適合它的工作負載,不妨使用 PyPy。

  “這是由于它是一種動態類型語言”

  在“靜態類型”語言中,你在聲明變量時必須指定變量的類型。這樣的語言包括C、C++、Java、C#和 Go。

  在動態類型語言中,仍然存在類型這個概念,但變量的類型是動態的。

  在這個示例中,Python 創建了一個有相同名稱、str 類型的第二個變量,并釋放為a的***個實例創建的內存。

  靜態類型語言不是為了給你添堵而設計的,它們是兼顧 CPU 的運行方式設計的。如果一切最終需要等同于簡單的二進制操作,你就得將對象和類型轉換成低級數據結構。

  Python 為你這么做這項工作,你永遠看不到,也不需要操心。

  不必聲明類型不是導致 Python 速度慢的原因,Python 語言的設計使你能夠讓幾乎一切都是動態的。你可以通過猴子補丁(monkey-patch),加入對運行時聲明的值進行低級系統調用的代碼。幾乎一切都有可能。

  正是這種設計使得優化 Python 異常困難。

  為了說明我的觀點,我將使用可在 Mac OS 中使用的一種名為 Dtrace 的系統調用跟蹤工具。CPython 發行版并未內置 DTrace,所以你得重新編譯 CPython。我使用 3.6.6 進行演示。

  現在 python.exe 將在整個代碼中使用 Dtrace 跟蹤器。保羅·羅斯(Paul Ross)寫了一篇關于 Dtrace 的雜談(https://github.com/paulross/dtrace-py#the-lightning-talk)。你可以下載 Python 的 DTrace 啟動文件(https://github.com/paulross/dtrace-py/tree/master/toolkit)來測量函數調用、執行時間、CPU 時間、系統調用和各種好玩的指標。比如

  py_callflow 跟蹤器顯示你應用程序中的所有函數調用。

  那么,Python 的動態類型會讓它變慢嗎?

  • 比較和轉換類型的開銷很大,每次讀取、寫入或引用一個變量,都要檢查類型。

  • 很難優化一種***動態性的語言。Python 的許多替代語言之所以快得多,原因在于它們為了性能在靈活性方面作出了犧牲。

  • Cython 結合了C-Static 類型和 Python 來優化類型已知的代碼,可以將性能提升 84 倍。

  結論

  Python 之所以速度慢,主要是由于動態性和多功能性。它可用作解決各種問題的工具,Python 有更優化、速度更快的幾個替代方案。

  然而,有一些方法可以優化你的 Python 應用程序,比如通過充分利用異步、深入了解分析工具以及考慮使用多個解釋器。

  對于啟動時間不重要、代碼會受益于 JIT 的應用程序來說,不妨考慮 PyPy。

  對于性能至關重要,又有更多靜態類型變量的部分代碼而言,不妨考慮使用 Cython。

責任編輯:張燕妮 來源: 云頭條
相關推薦

2024-06-04 16:59:54

2020-08-03 09:40:39

Python編程語言Instagram

2009-08-11 09:10:26

Windows 7系統提速

2021-05-08 06:10:11

React前端技術

2018-12-14 15:51:47

Pandas數據數據結構

2012-10-24 09:40:46

網絡優化系統優化

2021-11-03 06:28:21

Python運行速度開發

2018-08-16 08:03:21

Python語言解釋器

2010-05-10 13:21:16

Windows 7系統日志

2009-06-18 12:21:07

javascriptdom

2018-06-27 09:00:00

Linux運行速度CPU信息

2024-09-27 08:35:33

數組JavaScript性能

2016-02-22 09:27:18

2010-01-20 13:19:01

VB.NET錯誤處理

2010-04-12 10:01:43

Windows 7運行速度

2011-01-12 11:22:24

微軟認證

2024-12-17 09:44:55

2013-07-08 11:16:05

Windows 7

2009-09-12 09:43:29

Windows 7系統優化

2018-09-19 15:46:51

編程語言Python編譯器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲一区二区在线电影 | 视频一区在线 | 中文字幕在线观看视频网站 | 综合久久一区 | 91中文字幕在线观看 | 国产欧美一区二区精品忘忧草 | 久在线观看| 一区二区在线 | 精品视频免费在线 | 无码日韩精品一区二区免费 | 日韩av在线一区 | 欧美精品一区二区三区四区 在线 | 黄色中文字幕 | 国产一区二区高清在线 | 久久综合伊人一区二区三 | 国产一区二区在线免费视频 | 久久亚洲欧美日韩精品专区 | 91成人在线视频 | 天天搞天天操 | 欧美国产日韩一区二区三区 | 在线91| 亚洲精品视频播放 | 青青操91| 色婷婷久久久久swag精品 | 久久精品亚洲一区二区三区浴池 | 亚洲一区二区电影在线观看 | cao在线| 欧美美女一区二区 | 天天久久 | 亚洲男人天堂2024 | 亚洲一区中文字幕 | 精品久久久久久亚洲精品 | 国产成视频在线观看 | 精品自拍视频在线观看 | 成年免费大片黄在线观看一级 | av一二三区| 日本成人中文字幕在线观看 | 国产精品一二三区在线观看 | 国产精品久久久久久久午夜片 | 精品一区二区av | 亚洲精品在线播放 |