Python直譯器PyPy將配備新的JSON解析器,使得解析大型JSON檔案能夠更有效率,在執行速度以及記憶體容量表現,都比CPython以及Node的解析器都還要快上許多。這個新的JSON解析器將會在PyPy 7.2中釋出。

解析巨大的JSON檔案存在許多障礙,一部分是反序列工作需要花費很多時間,另一部分則是所產生的資料結構,還會占據大量的記憶體,容量甚至會比原始檔案還要大上許多倍,而且相對的,分配和初始化大資料結構的時間,也會比起小資料結構還要多上不少。新開發的PyPy JSON解析器,便是要來解決解析JSON花費過長的時間以及記憶體過多的問題。

新解析器的作者Carl Friedrich Bolz-Tereick提到,跟其他進階的實作方法比起來,這個JSON解析器有許多開發限制,他不想要更改Python程式Pexpect的json.loads API,也不想只支援具有SIMD擴充的CPU。他也表示,大部分的JIT都會針對典型的使用模式進行最佳化,犧牲非經常使用的模式,使得非常用模式在最佳化後可能變得更慢,而他試圖採用更通用的方法。

Carl Friedrich Bolz-Tereick以資料結構Maps來加速解析工作,Maps是常見用來最佳化動態語言VM中類別實例的常見方法。他在PyPy中組合不同的技術,實作了多種JSON解析器,並比較CPython simplejson、CPython ujson、Node 12.11.1的JSON解析器以及RapidJSON的速度。實驗用的中大型JSON檔案基準,包括來自Reddit的JSON檔案931.65 MiB、Censys的JSON檔達898.45 MiB、Gharchive則有276.34 MiB以及來自Wikidata的檔案119.75 MiB等。

首先Carl Friedrich Bolz-Tereick比較了PyPy各版本的JSON解析器解決方案,PyPyBaseline為PyPy 5.8版本提供的JSON解析器,PyPyKeyStringCaching則是PyPy 5.9版本的JSON解析器,特性是會記憶字典的鍵值字串,PyPyMapNoCache類似PyPyKeyStringCaching,但是使用Maps來表達字典,也不快取非鍵值字串,PyPyFull則是將會隨著PyPy 7.2釋出的最新JSON解析器,與PyPyMapNoCache作法類似,但是對全字串進行快取。

(下圖)PyPy各種JSON解碼實作的時間相比,並以PyPyFull的執行時間當作基準正規化時間,圖中可以看到PyPyBaseline總是花費最多時間,第二慢的則是PyPyKeyStringCaching,接下來是PyPyMapNoCache,雖然處理Gharchive和Reddit兩個服務的JSON檔案,PyPyMapNoCache略快於PyPyFull,但普遍來說PyPyFull的執行速度都是最快的。

而JSON資料結構容量相比(下圖),PyPyFull的表現都是最好的,占據記憶體的容量都只比原始檔案多一點點,甚至處理Yelp檔案所使用的記憶體,還幾乎與原始檔案大小相同。

與其他技術實作相比,執行速度PyPyFull大勝simplejson、ujson、Node的JSON解析器,跟RapidJSON相比則是小輸(下圖)。在資料結構大小的比較,PyPyFull大贏simplejson和ujson,小贏RapidJSON,但是普遍都比Node的JSON解析器占用的記憶體還要多。

Carl Friedrich Bolz-Tereick表示,PyPy新的JSON解析器實作獲得大幅速度提升,打敗了CPython以及Node,但是RapidJSON還是位居明顯的領先位置,他提到,之所以PyPy的速度會差RapidJSON這麼多,是因為垃圾回收機制的關係,導致大型JSON檔案仍然花費太多時間在反序列化。在記憶體方面,明顯的Node占優勢,Carl Friedrich Bolz-Tereick認為,這是因為在記憶體中,Python表達物件的方式所造成的問題。


Advertisement

更多 iThome相關內容