日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

c#和python同一主机直接udp_为什么Python 如此之慢

發布時間:2023/12/10 C# 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c#和python同一主机直接udp_为什么Python 如此之慢 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文:

https://hackernoon.com/why-is-python-so-slow-e5074b6fe55b?hackernoon.com

Python 正在爆炸般流行起來,它被用于DevOps, 數據處理,web開發和安全領域。但是在速度方面卻沒有取得過什么勝利。
Java在速度方面和C/C++/C#/Python比起來如何?答案很大程度上取決于你所運行的應用。沒有什么跑分是完美的,但是編程語言測評游戲(Computer Language Benchmarks Game)是一個很好的切入點。

十多年來編程語言測評游戲一直對我來說是一個參考,相比于其他語言,比如Java, C#, Go, JavaScript, C++, Python是最慢的語言之一。這些語言中包含了JIT編譯器(c#, java),AOT編譯器(c/c++)和解釋型語言js。

注意: 當我說“Python”, 我說的是Python的參考實現CPython, 其他實現這篇文章也會提到。 這篇文章想要回答的一個問題就是:當Python執行一個相同的程序要比別的語言實現慢2-10倍的時候,為什么會這么慢,難道我們不能讓它跑的更快嗎?

下面說一下本文的主要觀點(當然也是客觀事實): "因為Python 有GIL(Global Interpreter Lock, 全局解釋鎖)" “因為Python 是解釋型語言而不是編譯型” “因為Python 是動態類型語言” 哪一個原因影響最大對速度影響最大呢?

GIL

現代計算機的cpu有多核,有時候有多個處理器。為了充分利用多出來的處理能力,操作系統定義了一種更加低級別的單位:線程,讓一個進程可以啟動多個線程來執行系統指令。 這樣的話如果一個進程的CPU資源非常緊張,負載就會均勻的平攤到各個CPU核心,這種方法能夠很高效地讓大多數任務更快完成。 當我寫這篇文章的時候,我的Chrome瀏覽器開啟了44個線程。要記住的是線程的結構和api在POSIX-based的系統(OSX, Linux)和Windows下面是不一樣的。操作系統同樣會管理線程的調度。 如果你沒有進行過多線程編程,你需要快速熟悉一下"鎖"的概念。不像單線程的進程,多線程的進程中,當你更改內存中的變量,你需要確認多個線程不會同時嘗試訪問或修改同一個內存塊。

當CPython創建變量,它會給變量分配內存空間并且計算變量的引用數,如果引用數為0, Python將會釋放掉這塊內存,這就是為什么for循環表達式里的臨時變量不會讓內存爆炸。也是CPython的垃圾回收機制。

接下來的挑戰是,當變量被多個線程共享時,如何鎖住引用數。Python程序執行過程中有一個全局解釋鎖GIL 小心地控制著線程的執行。Python解釋器在同一時間只能執行一個操作,不論有多少個線程。

這對于Python應用的性能表現意味著什么呢?

如果你的應用是單線程單解釋器的,這對你的應用性能毫無影響。移除GIL也不會對你的應用性能有任何影響。 如果你想在同一個解釋器中使用線程進行并發操作,并且你的線程是IO密集型的,那你就會看到GIL的資源爭奪。

David Beazley的博客中對多線程程序中 GIL 的作用進行了可視化:http://dabeaz.blogspot.com/2010/01/python-gil-visualized.html

下圖表示了Python多線程程序中GIL的分配情況。

如果一個Python程序里有多個線程,一個程序運行的時候會拿著GIL,當遇到I/O的時候會放開GIL,但是CPU-bound的線程通常不會進行I/O。Python切換線程的一種作法是每100 ticks檢查一下,可以通過sys.setcheckinterval()修改這個數值。 綜上所述,因為Python線程不能有效利用多核,但是增加了CPU context switch的消耗,所以對于CPU-bound的程序表現很差。更糟糕的是,在多核情況下可能表現會更差,因為系統支持多線程運行但是GIL保證只有一個線程運行,這時候多線程會反復的檢查GIL是否被釋放,但是拿不到GIL(因為有太多線程競爭),有可能導致系統發生Trashing現象。

如果你使用一個web應用(Django)并且使用WSGI,每個請求會有一個單獨的Python解釋器,由于Python的全局解釋鎖啟動很慢,所以有的WSGI實現會有一個“守護模式”,就是先把Python進程啟動起來放著,等待請求進來使用。

那其他的Python實現呢?

PyPy也有GIL但是比CPython快超過三倍。 JPython 沒有GIL, 因為JPython的線程代表一個Java線程,得益于JVM的內存管理機制,JPython不使用GIL。

JavaScript是怎么做的呢

首先所有的Javascript 引擎使用標記-清除的垃圾回收機制。 上面提到過, GIL的需求主要是因為CPython的內存管理算法。 JavaScript 沒有GIL, 但它同時也是單線程的所以它并不需要GIL。JavaScript使用事件循環和Promise/Callback實現異步的編程而不是使用并發。Python也有類似實現asyncio

“因為Python是解釋型語言”

我經常聽說這個言論,我覺得這是一個對于CPython執行方式的粗暴簡化。 如果你在終端執行一個命令(比如python myscript.py),CPython會開始順序執行一大串任務: 讀取,詞法分析,解析,編譯,解釋,執行代碼。

一個重點是.pyc文件的創建。在編譯階段,字節碼串被寫到pycache/下(3.x)或者和py文件相同的文件夾(2.x)。這個操作不僅對你自己的代碼有效,也包括所有你導入的模塊。

所以大多數情況下,Python在本地解釋和執行字節碼,與之相比 Java 和 C#.NET:

Java 編譯成一個“中間語言”,然后JVM讀字節碼實時將其轉化為機器碼,.NET的CIL也一樣,.NET CLR(Common-Language-Runtime, 通用語言運行時),使用的是實時編譯到機器碼(JIT)。

所以,如果它們都用到了虛擬機和部分字節碼,為什么Python在跑分上比Java/C#慢這么多呢?

Java/C# 是即時編譯(JIT)的。
JIT要求一個中間語言,以便讓代碼轉換成區塊。AOT編譯是為了可以在交互前保證CPU能理解每一行代碼。
JIT本身不會讓執行速度更快,以為它仍然是在執行相同的字節碼, 然而JIT可以讓實時優化成為可能,一個好的JIT編譯器應用的那一部分被執行很多次,這些部分被稱為“熱點”。 這樣編譯器會將這些部分替換成更加高效的版本。這意味著如果你的程序重復做相同的事情,使用JIT就能顯著提高速度。同時Java/C#是強類型的語言所以優化器可以對語言作出更多預設。

PyPy 使用JIT,前面提到,它比CPython快得多。

所以為什么CPython不用JIT呢

JIT有很多缺點,其中一個就是啟動慢。

CPython 啟動已經相對很慢了, PyPy比CPython啟動慢CPython2-3倍。JVM啟動是出了名的慢。.NET CLR使用隨操作系統啟動來解決這個問題, 但CLR的開發者同時也是其依賴的系統的開發者(win)。

如果你的Python是單進程,運行時間很長,并且有很多重復操作可以被優化,那么使用JIT就很有意義。 但是CPython是通用實現,當使用Python開發命令行工具,每次都等待JIT啟動是非常糟糕的體驗。 CPython需要服務于盡可能廣泛的場景,有可能使用JIT反而會大幅度拖累系統性能。 如果你需要使用JIT并且有一個適合的工作場景,那可以使用PyPy。

“因為Python是動態類型語言”

在靜態類型語言中,聲明變量之前需要聲明變量類型,包括 C, C++, Java, C#, Go。動態類型語言中仍然有類型的概念,但是變量的類型可變。

a

這個小例子中, Python 使用相同的變量名創建了類型不同的第二個變量,釋放掉了第一個變量的內存空間。
靜態類型語言并不是為了麻煩你而設計的,而是根據CPU行為設計的。如果所有的行為最終會變成二進制操作,你必須將對象轉換成更加底層的數據結構。

Python為你代勞了轉換到底層數據結構這一步,所以你不用關心。當然不用聲明變量并不是Python慢的原因。 Python語言的設計極為靈活,幾乎所有東西都能變成動態的,比如猴子補丁。這種設計讓Python的優化變得難以想象的困難。

猴子補丁: 1. 在運行時替換方法、屬性等 2. 在不修改第三方代碼的情況下增加原來不支持的功能 3. 在運行時為內存中的對象增加patch而不是在磁盤的源代碼中增加

python中一個很簡單的例子:

import

所以是Python的動態性讓它如此慢嗎?

比較和轉換類型非常耗費資源, 每次對變量讀寫、引用都需要檢查類型。如此動態化的語言是很難優化的,很多Python的不同實現能更快是因為為了性能在靈活性方面做了妥協。

比如CPython, 將C語言的靜態類型和Python結合,這些靜態類型能提供84倍的性能優化。

結論

Python這么慢主要是因為動態的生態和它的多功能性。它能用來解決所有類型的問題,所以在不同領域我們可以選擇更加快速的Python版本。
有很多方法可以用來優化你的Python程序,比如活用async, 了解分析工具, 考慮使用多個解釋器等等。比如一些啟動時間不重要的應用,或者能夠能JIT獲益的程序我們可以使用PyPy。如果你的代碼有些部分非常要求性能,又使用了很多C語言的靜態類型,那么選擇Cython。

總結

以上是生活随笔為你收集整理的c#和python同一主机直接udp_为什么Python 如此之慢的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。