日本一区二区三区久久久久久久久不_日韩精品一区二区三区三区免费_精品视频一区二区不卡_欧美剧情片在线观看_欧美日韩免费在线视频_欧美成人精品3d动漫h_欧美激情中文字幕一区二区_91色九色蝌蚪_国产做a爰片久久毛片_久久久国产午夜精品_美女视频免费一区_日韩一级免费观看_日本一区二区三区四区在线视频_亚洲三级小视频_久久男人中文字幕资源站_欧美岛国在线观看

二維碼
企資網

掃一掃關注

當前位置: 首頁 » 企業資訊 » 行業 » 正文

一次程序優化經歷,運行8小時到3小時到50分

放大字體  縮小字體 發布日期:2021-09-14 04:28:56    作者:企資小編    瀏覽次數:96
導讀

上周我遇到一個需要處理大文件的場景,需要遍歷大文件,并且對數據進行一定的處理。由于這批數據對時效性要求較高,所以當時我編寫的程序是希望運行地越快越好,所以我在編程的過程中對程序進行一次一次的優化,最終

上周我遇到一個需要處理大文件的場景,需要遍歷大文件,并且對數據進行一定的處理。由于這批數據對時效性要求較高,所以當時我編寫的程序是希望運行地越快越好,所以我在編程的過程中對程序進行一次一次的優化,最終從開始時需要運行8小時到現在只需運行50分鐘,算是達到了需求。當然,你可能會說一開始的程序寫得太爛,所以導致運行太緊,無所謂啦,這并不是重點。實際上,很多人第一次寫程序都很難按預想那樣寫出簡單高效的代碼片段,只是有的場景對性能要求并不高,所以有的人看著自己的程序能運行后就不再進行優化了。其實,絕大多數程序都是有優化空間的,并且還有很大的優化空間,這個空間指的是時間和空間。

廢話不多說,我把這次優化的過程和思路總結為8個點,分享出來,希望能對大家有所幫助。

1 需求

大數據時代,處理大量數據成為了不少程序員的家常便飯。那么多大的數據可以稱為大數據呢?對于數據量,很難用一個確定的量去描述其界限,我理解大數據不僅僅是數據量大,還應該具有數據復雜的特性,比如維度高、字段多。我平時處理的數據并不是大到磁盤都存不下那種,最多就是億的量級。此次處理的數據是一個文本的大文件,數據量不到一億,占用磁盤空間幾百GB,它是行列結構,即每一行數據用tab鍵分割,有不到100個字段,其中有部分字段是json,且這個json異常復雜,一條大的數據可能會占用好幾MB的空間。

我要做的事情很簡單,最費勁的就是在每一條數據的大json串中增加一個字段,這個字段經過了一些復雜的計算。簡單來說就是寫程序遍歷一遍這個文件,然后對每條數據做一些計算,其中包含了把一個字段塞到大json串中。

2 Python

說到處理數據,我個人覺得Python是最好用的,當然它最caodan的地方是對中文編碼不夠支持,不過這還算是一個可以克服的缺點。和往常一樣,我用Python編寫了一版,試著跑了一下數據,大約每一萬條數據需要大約耗費5秒。算下來,大概需要跑8到10小時,這是不能接受的,所以我開始了一系列的優化。

另外多說一點,我們在測試自己的程序的時候,并不用全量的數據去測,比如從正式數據中去head(Linux命令,可以取文件頭部的n行數據)出200萬條數據來進行測試,跑完測試用例就可以大致估算出整個程序耗時了。

3 并發

因為程序中包含了一定的計算邏輯,即消耗CPU的邏輯片段(說個題外話,有的程序可能是計算型的,比較耗CPU,有的是內存型的,比較耗內存,還有些是IO型的,大多數情況下磁盤讀寫會成為瓶頸),可能是受之前慣性思維的影響,對于優化的方法,我首先想到的就是增加程序的并發,開多個線程,開多個進程。多線程最簡單,一是好實現,二是代碼相對好控制。三下兩下把代碼改成了多線程,這里我使用的是線程池而不是每來一條數據新創建一個線程去處理它,這樣可以減少程序的運行時間。所謂線程池就是,事先,一般在程序啟動的時候先創建一定數量的線程,然后每次有處理需求時,就從線程池中撈一個線程來處理它,因為線程的創建和消亡是會消耗資源和時間的,所以,理論上,使用線程池就可以減少這部分創建和消亡的時間。

我一開始創建了8個線程,運行了一下,程序并沒有快多少,所以我又把線程數提到了16,最后提到了128,運行速度反而減慢了。還是因為慣性思維,因為Python的線程模型是N:1模型。所謂N:1模型就是所有線程都跑在了一個物理核上,不同線程實際上是在同一個核上頻繁切換。我認為多線程已經把一個核給榨干了,要提升程序的運行速度只能采取多進程。如果在CPU相對空閑時,不同的進程幾乎是可以獨占不同的物理核的,準確來說就是切換不太頻繁,可以實現真正意義上的并發。說到多進程,對于處理大文件,程序運行最快的方法是將一個大文件按行平均切割成m份,然后開啟m個進程獨立地跑這些數據。不過按照之前的經驗,使用Linux下的文件切割命令split來切割這么一個大文件,大概需要3個小時,這屬于程序員的額外時間消耗,所以我放棄了。我還是選擇了進程池,在程序啟動的時候主進程fork出許多子進程,即master/worker模式,并且自己實現了一個生產者消費者,否則任務等待隊列會被撐爆的。代碼寫好了以后,根據我的以往實驗,在開啟5個進程的時候程序運行得最快,并且總的運行時間是之前的80%左右。優化效果并不好,因為進程池也會存在進程的切換,和真正獨立的進程是有區別的。這幾個進程不是一直在running狀態,也是會經歷進程的狀態切換,running、wait、ready等狀態。從8個小時縮短為6個多小時是遠遠不達標的,至少要在兩個小時內才能接受。

4 瓶頸

瞎搞了這么久,我終于想著去理性地尋找瓶頸,一種最好的方式就是在程序運行的時候實時監控計算機的狀態,比如大家熟知的命令top,第三方工具htop。我這里使用的是公司內部的監控工具,可以查看內存、CPU、IO的實時狀態。還有另一種方式就是計算程序每個部分的耗時,如果你的程序封裝或者抽象得足夠好,我們是很容易計算某個代碼片段的耗時的,比如計算在程序流程中某個函數需要運行多長時間,我們只用在調用函數之前打印一下Unix時間戳,然后在函數運行結束的時候打印時間戳,最后做個差就能算出耗時了。所以說我們的程序要高內聚、低耦合,這樣后期維護起來是很爽的。經查看,我發現,在單線程的情況下,每處理一萬條數據大致耗時5秒,其中計算只花費了不到一秒,中文編碼解碼耗時不到一秒,IO耗時差不多兩秒,其中最耗時的就是解大json(json的decode和encode的步驟),耗時兩秒多一點。通過監控計算機狀態,在程序運行的時候我讀寫的那塊磁盤的IO被打滿了,原因是服務器上還有很多其他進程在讀寫這塊磁盤。

所以這里有兩個優化點,第一點就是優化IO,第二點就是把大json解包封包的時間縮短。

5 換磁盤

說到IO,很多同學第一時間想到的就是換塊SSD。換塊SSD當然是個很好的解決辦法,但是如果每次編寫程序遇到IO問題都要通過硬件來優化,公司豈不是得破產?程序員寫代碼并不是想要啥就有啥的,要用最小的預算達到目的。我所使用的服務器上并沒有掛載SSD磁盤,倒是掛載了很多機械盤,并且很多盤都沒有讀寫操作。在大多數情況下,我們所說的IO基本上都指的是某一塊磁盤的IO。這里有一個優化點就是,我把讀寫的磁盤分離開,還是從之前的那塊磁盤讀數據,但是往另外一塊磁盤寫數據。還是原來的單線程代碼,什么也沒有改變,程序的運行時間一下降低了四分之一。從8小時縮短為6小時。

6 算法

IO進行了一定的優化,接下來就該優化最耗時的json解包封包了。我使用的是Python的官方工具,json.loads和json.dumps。事實上,有時候官方的工具并不一定是最好的,就拿json處理的相關工具來說,同一種語言可能有很多不同的工具,它們的處理效率可能會相差10倍以上。接下來的操作是不是該換個json解包封包工具了?我并不想這么做,因為有更快的方式,不知道大家還記得我前文提到的一句話嗎?我是想在json串中增加一個字段,在多數情況下,增加比減少容易得多。既然是增加,那完全沒有必要解包,正常情況下,我們從文件中讀取的json串實際上是一個字符串,解包會把它變為一個dict,處理完,又把這個dict轉化為一個字符串,然后再寫入文件。實際上,我們可以省略string轉dict再從dict轉string的步驟,因為json字符串的末尾是一個}符號,那么我們直接在}插入想要添加的字段即可。舉個例子:加入原始的json字符串是:{"key1":"value1"} ,我們想要加上一個字段key2,那么可以直接對字符串做切片操作(切片是Python中的一個操作)。即可以直接把這個過程變成 {"key1":"value1" + "key2":"value2" + }。這么一做,程序運行從之前的6小時縮短為3小時,處理時間減少了一倍,這算是在算法上的提升。

7 語言

3小時雖然已經比最開始的8小時快很多了,但我還是嫌棄它太長。Python雖然比較適合處理數據,寫起來也比較容易,不過比較偏上層,無法進行更底層的控制,比如內存、線程、進程等。都說Go語言的運行效率接近C++,開發效率接近Python,所以我也準備嘗嘗鮮。Go語言是編譯型語言,并且其語言本身就支持進程線程等特性。當然,這里我并沒使用并發,我只是用Go把之前的Python代碼重新寫了一遍,不過還是做了適當的優化。

1. 為了讓IO充分使用,我將Python一行一行的讀寫改為了Go語言一塊一塊的讀寫,即之前是一次讀一行,現在是一次讀一塊固定大小的二進制,然后用換行符來區分這一塊里面的每一行,誰快誰慢一下就能見分曉。

2. 我給文件的讀寫各添加了一個30MB的緩存,構成兩個生產者消費者。對寫操作來說,生產者是代碼處理邏輯,消費者是IO寫。經測試,生產者的速度是快于消費者的(所以這里提高并發已經沒有什么意義了,瓶頸在IO)。

在這種情況下,最后整個程序運行完成只需要50分鐘,已經在兩個小時內了,符合了最初的需求。

8 Todo

其實這個程序還有優化的空間,因為已經符合我最開始的需求,我就沒有繼續再優化下去。我剛說到,程序的瓶頸在于IO寫。那么我們可以同時往掛載在同一臺機器上的多個磁盤循環寫,這樣就能分散每塊磁盤的IO了。不過,寫程序不能為了優化而優化,在開發效率和運行效率上我們要選擇一個折中點。再盲目繼續優化,代碼的復雜度就該上升了。

 
(文/企資小編)
免責聲明
本文僅代表作發布者:企資小編個人觀點,本站未對其內容進行核實,請讀者僅做參考,如若文中涉及有違公德、觸犯法律的內容,一經發現,立即刪除,需自行承擔相應責任。涉及到版權或其他問題,請及時聯系我們刪除處理郵件:weilaitui@qq.com。
 

Copyright ? 2016 - 2025 - 企資網 48903.COM All Rights Reserved 粵公網安備 44030702000589號

粵ICP備16078936號

微信

關注
微信

微信二維碼

WAP二維碼

客服

聯系
客服

聯系客服:

在線QQ: 303377504

客服電話: 020-82301567

E_mail郵箱: weilaitui@qq.com

微信公眾號: weishitui

客服001 客服002 客服003

工作時間:

周一至周五: 09:00 - 18:00

反饋

用戶
反饋

日本一区二区三区久久久久久久久不_日韩精品一区二区三区三区免费_精品视频一区二区不卡_欧美剧情片在线观看_欧美日韩免费在线视频_欧美成人精品3d动漫h_欧美激情中文字幕一区二区_91色九色蝌蚪_国产做a爰片久久毛片_久久久国产午夜精品_美女视频免费一区_日韩一级免费观看_日本一区二区三区四区在线视频_亚洲三级小视频_久久男人中文字幕资源站_欧美岛国在线观看
亚洲精品一区二区三| 国产视频在线观看一区| 天堂资源在线中文精品| 亚洲一区精品在线| 一区二区三区资源| 夜夜嗨av一区二区三区| 亚洲一区日韩精品中文字幕| 午夜精品免费在线| 蜜臀av亚洲一区中文字幕| 美女视频黄a大片欧美| 青椒成人免费视频| 国内精品嫩模私拍在线| 成人在线综合网| 国产成人亚洲欧美| 欧美一二三四五区| 在线观看日韩毛片| 欧美一个色资源| 欧美国产1区2区| 亚洲国产精品久久人人爱蜜臀| 日本中文在线一区| 成人av网站在线| 久久久久久艹| 在线观看欧美亚洲| 3atv一区二区三区| 国产嫩草影院久久久久| 一区二区三区四区av| 六月丁香综合在线视频| 成人动漫一区二区三区| 久久狠狠久久综合桃花| 欧美性感一区二区三区| 国产午夜精品一区二区三区四区| 亚洲黄色免费电影| 精品亚洲成av人在线观看| 91女人视频在线观看| 日本亚洲自拍| 欧美日韩国产免费一区二区| 国产亚洲人成网站| 丝袜a∨在线一区二区三区不卡| 成人午夜免费av| 日韩精品久久久| 日韩欧美精品三级| 亚洲一区二区三区四区在线观看| 精品一区二区在线看| 99国产一区二区三精品乱码| 欧洲精品码一区二区三区免费看| 4438亚洲最大| 亚洲最大的成人av| 丁香婷婷综合网| 亚洲精品无人区| 久久蜜臀中文字幕| 美女视频黄免费的久久 | 奇米四色…亚洲| 91国产在线播放| 日本韩国一区二区三区| 国产精品高潮呻吟| 国产不卡一区视频| 一区二区三区我不卡| 久久久国产精品午夜一区ai换脸| 蜜臀av性久久久久av蜜臀妖精| 国产精品一区二区三区不卡| 欧美嫩在线观看| 午夜av一区二区三区| 草莓视频一区| 欧美另类z0zxhd电影| 亚洲小说春色综合另类电影| 91麻豆福利精品推荐| 欧美日韩国产综合草草| 亚洲自拍偷拍欧美| 国产精品久久久久av福利动漫| 在线电影院国产精品| 免费人成黄页网站在线一区二区| 欧美精品一区二区视频| 日本一区二区三区四区| 99在线精品视频| 91精品在线麻豆| 久久97超碰国产精品超碰| 色播五月综合| 亚洲蜜臀av乱码久久精品蜜桃| 91一区二区三区| wwwwxxxxx欧美| 国产酒店精品激情| 欧美色综合久久| 日本三级韩国三级欧美三级| 日韩aⅴ视频一区二区三区| 欧美韩国日本不卡| av一区二区三区在线| 欧美高清性hdvideosex| 久草精品在线观看| 日本韩国一区二区三区| 日韩成人av影视| 91黄色激情网站| 日韩成人精品视频| 日本乱人伦aⅴ精品| 日本亚洲免费观看| 欧美视频一区二区在线观看| 丝袜亚洲另类欧美综合| 亚洲国产精品123| 亚洲国产精品久久不卡毛片| 日韩福利视频| 视频一区二区中文字幕| 色婷婷亚洲一区二区三区| 日韩精品欧美精品| 欧美日韩在线播放| 国产精一区二区三区| 欧美一区二区三区在| 波多野结衣亚洲一区| 久久久亚洲精品一区二区三区 | 国产亚洲人成网站| 99re6热在线精品视频播放速度| 久久青草欧美一区二区三区| 91老司机福利 在线| 欧美国产精品v| 欧美精彩一区二区三区| 一区二区三区精品在线观看| 欧美亚洲另类在线一区二区三区| 亚洲一区二区三区在线| 在线免费观看日韩欧美| 国产精品影视网| 久久亚洲捆绑美女| 国产一区二区三区高清| 亚洲一区二区三区不卡国产欧美| 色婷婷狠狠综合| 国产**成人网毛片九色 | 成人97人人超碰人人99| 久久久亚洲精品石原莉奈| 久久精品国产美女| 亚洲一区二区三区四区中文字幕| 色成人在线视频| 高清国产一区二区| 国产精品乱码人人做人人爱 | 久久久久久久久久久久久久久99 | 亚洲美女网站18| 久久99精品久久久久久动态图 | 欧美一区二区成人6969| 91亚色免费| 偷拍一区二区三区四区| 91精品在线免费| 国内一区二区在线视频观看| 亚洲成人在线免费| 欧美变态tickle挠乳网站| 精选一区二区三区四区五区| 久久草av在线| 国产精品色哟哟网站| 在线视频精品一区| av电影一区二区| 亚洲国产综合人成综合网站| 91精品国产色综合久久| 美国av一区二区三区| 国产在线看一区| 亚洲男人的天堂在线aⅴ视频| 欧美日韩在线精品一区二区三区激情| 97久久超碰国产精品| 水野朝阳av一区二区三区| 久久久久久久久久久电影| 亚洲精品国产系列| www.av精品| 日韩高清一区二区| 中文字幕第一区| 777a∨成人精品桃花网| 欧美日韩在线一二三| 成人短视频下载| 日本最新不卡在线| 日韩毛片高清在线播放| 欧美一区二区精品久久911| 亚洲第一在线综合在线| 91污片在线观看| 激情文学综合网| 夜色激情一区二区| 国产欧美日产一区| 在线电影一区二区三区| 欧美日韩无遮挡| 91视频xxxx| 国产精品资源站在线| 亚洲6080在线| 综合av第一页| 精品久久人人做人人爱| 91久久精品一区二区二区| 久久综合婷婷综合| 91在线精品一区二区| 国产专区综合网| 午夜伊人狠狠久久| 成人免费小视频| 久久尤物电影视频在线观看| 欧美色图天堂网| 亚洲欧洲一区二区福利| 国产一区喷水| 91麻豆精品一区二区三区| 国产suv精品一区二区三区| 日韩国产在线一| 亚洲高清视频在线| 成人免费一区二区三区视频| 久久精品人人做人人爽97| 欧美肥胖老妇做爰| 欧美视频一区二区三区在线观看| 亚洲精品二区| 日韩视频专区| 美脚丝袜一区二区三区在线观看| 成人黄色片视频网站| 91麻豆国产在线观看| 97久久久精品综合88久久|