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

1分鐘插入10億行數據!拋棄Python,寫腳本請使用Rust

新聞 開發
近日,一位程序員急需在一分鐘之內生成十億行的測試數據庫,然而在用Python寫了腳本之后發現「大失敗」。怎么辦?當然是用Rust了!

 [[412076]]

最近,一位程序員表示自己急需一個「也就」十億行數據的測試數據庫,并且還得在一分鐘之內生成。

于是,他做了一個所有程序員都會做的事:寫一個Python腳本來生成數據庫。

然而,很不幸的是,這個腳本非 常慢。

[[412077]]

于是,他又做了一個所有程序員都會做的事:進一步學習關于SQLite、Python以及不知道為什么還有Rust的知識。

項目已開源:https://github.com/avinassh/fast-sqlite3-inserts

目標

作者需要在他2019年的MacBook Pro(2.4GHz四核i5)上,一分鐘內生成一個有10億行的SQLite數據庫。

1分鐘插入10億行數據!拋棄Python,寫腳本請使用Rust

表的模式

要求:

  1. 生成的數據是隨機的;
  2. 「area」列將包含六位數的地區代碼(任何六位數都可以,不需要驗證);
  3. 「age」列是5、10或15中的任何一個;
  4. 「active」列是0或1。

不過,作者表示,對腳本的要求也不用太高,還是可以妥協的:

  1. 如果進程崩潰,所有的數據都丟失也沒有問題,再次運行腳本就可以了;
  2. 允許充分利用電腦的資源:100%的CPU,8GB的內存和剩余的SSD儲存;
  3. 不需要使用真正的隨機方法,來自stdlib的偽隨機方法就可以。

Python原型

在最開始的腳本中,作者試圖在一個for循環中逐一插入1000萬條記錄,而這讓用時直接達到了15分鐘。

1分鐘插入10億行數據!拋棄Python,寫腳本請使用Rust

顯然,這太慢了。

在SQLite中,每次插入都是一個事務,每個事務都保證它被寫入磁盤,作者推斷可能問題就來自這里。

于是作者開始嘗試不同規模的批量插入,發現10萬是一個最佳點,而運行時間減少到了10分鐘。

1分鐘插入10億行數據!拋棄Python,寫腳本請使用Rust

SQLite優化

作者認為自己寫的代碼已經很簡練了,并沒有什么可以優化的空間。

于是他將下一個目標轉到了數據庫的優化。

根據各種關于SQLite優化的建議,作者做了一些改進。

1分鐘插入10億行數據!拋棄Python,寫腳本請使用Rust
  • 關閉「journal_mode」將禁用回滾日志,也就是說,如果任何事務失敗,都無法回滾。
  • 關閉「synchronous」,將使SQLite不再關心是否能可靠地寫入磁盤,而是把這個責任交給操作系統。也就是說,可能會出現SQLite并沒有成功寫入磁盤的情況。
  • 「cache_size」指定了SQLite在內存中可以保留多少個內存頁。
  • 當「locking_mode」為「EXCLUSIVE」模式時,SQLite鎖住的連接將永遠不會被釋放。
  • 將「temp_store」設置為「MEMORY」可以讓其表現像一個內存數據庫。

此處作者提醒,請不要把這些操作用到生產上去。

重新審視Python

作者再次重寫了Python腳本,這次包括了微調的SQLite參數,這次帶來了巨大的提升,運行時間大幅減少:

  • 原始的for循環版本用時大約10分鐘。
  • 批處理版本用時大約8.5分鐘。

PyPy

PyPy在其主頁上強調它比CPython快4倍,于是作者決定嘗試一下。

令作者有些意外的是,竟然不需要對現有的代碼進行任何改動,只需要在PyPy運行就可以了。

批處理版本只需要2.5分鐘,也就是速度快了接近3.5倍。

Busy Loop?

莫非是在Python的循環上耗費了太多時間?于是作者刪除了SQL指令之后再次跑了一遍代碼:

  • 批處理版本在CPython中用時5.5分鐘。
  • 批處理版本在PyPy中用時1.5分鐘(又是3.5倍的速度提升)。

然而用Rust重寫了相同的內容之后,循環只需要17秒。

于是,作者果斷拋棄Python,轉投Rust的懷抱。

1分鐘插入10億行數據!拋棄Python,寫腳本請使用Rust

Rust

像Python一樣,作者先寫了一個原始的Rust版本,一個循環執行一行數據的插入。

然而,即便使用了所有SQLite的優化,也依然消耗了大約3分鐘。于是作者進行了進一步的測試:

  • 嘗試把「rusqlite」換成異步運行的「sqlx」,這讓用時直接被拉到了14分鐘。作者表示,這比自己迄今為止寫的任何一個Python迭代都要差。
  • 在執行原始SQL語句時,使用準備好的語句。這個版本的用時只有1分鐘。

最優的版本

使用準備好的語句,以50行為一個批次插入,最終用時34.3秒。

作者又寫了一個線程版本,其中一個線程從通道接收數據,還有四個線程向通道推送數據。

這個也是目前性能最好的版本,最終用時大約32.37秒。

1分鐘插入10億行數據!拋棄Python,寫腳本請使用Rust
1分鐘插入10億行數據!拋棄Python,寫腳本請使用Rust
1分鐘插入10億行數據!拋棄Python,寫腳本請使用Rust
1分鐘插入10億行數據!拋棄Python,寫腳本請使用Rust

IO時間

SQLite論壇上的網友提出了一個有趣的想法:測量內存數據庫所需的時間。

于是作者又跑了一遍代碼,將數據庫的位置設定為「:memory:」,rust版本完成的時間少了兩秒(29秒)。

也就是說將1億條記錄寫入到磁盤上需要2秒,這個用時似乎也是合理的。

這也說明,可能沒有更多的SQLite優化可以以更快的方式寫入磁盤,因為99%的時間都花在生成和添加數據上。

排行榜 

插入1億行數據的用時:

Rust33秒 PyPy126秒 CPython210秒

總結

  1. 盡可能使用SQLite PRAGMA語句
  1. 使用準備好的語句
  1. 進行分批插入
  1. PyPy確實比CPython快4倍
  1. 異步不一定更快

目前,第二快的版本是單線程運行的,而作者的電腦有4個核心,于是他在一分鐘內可以得到8億行數據。然后再經過幾秒鐘的數據合并,時間仍然可以少于一分鐘。

網友評論

博主的這一番研究獲得了網友們的一致好評。

1分鐘插入10億行數據!拋棄Python,寫腳本請使用Rust

真的很喜歡這些觀點:

學習了更多關于PRAGMA語句。

PyPy的效率和靈活性可以通過即插即用的方式體現(將來一定會給它一個機會)。

文章的排版非常簡單,有適當的源代碼鏈接。很有趣,很容易上手。

Rust高光時刻又來了!

責任編輯:張燕妮 來源: 新智元
相關推薦

2024-12-19 07:50:00

2017-03-15 09:34:26

華為軟件開發

2021-09-07 10:55:36

SQLitePythonRust

2018-11-28 11:20:53

Python函數式編程編程語言

2021-07-15 06:43:11

Bash調試腳本

2013-09-13 14:08:01

2014-04-22 09:42:12

Bash腳本教程

2018-02-01 14:15:00

Python函數

2019-07-18 16:32:06

Python函數數據

2021-04-23 09:50:41

topLinux命令

2020-10-13 18:22:58

DevOps工具開發

2014-08-08 09:30:04

android scrollview

2023-10-12 11:48:18

SkyWalking工具

2020-08-13 13:51:22

Python數據庫插入數據

2017-03-16 08:46:57

延時消息環形隊列數據結構

2015-11-23 17:34:33

秒借

2018-03-12 21:31:24

區塊鏈

2021-08-02 13:20:31

代碼Python文件

2018-04-24 14:52:48

LinuxBash腳本

2023-12-25 14:50:39

Python迭代器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚欧午夜| 91网站视频在线观看 | 国产精品久久久久久久久久久久 | 亚洲三级av| 亚洲一区二区久久 | 精品中文在线 | 精品国产一区二区三区久久久蜜月 | 国产视频一视频二 | 亚洲视频二区 | 亚洲精品国产一区 | 国产a视频 | 人成精品| 盗摄精品av一区二区三区 | 99福利视频 | 国产福利在线 | 亚洲精品电影 | 国产成人精品视频 | 美女视频黄色的 | 国产激情自拍视频 | 国产精品久久亚洲 | 国产精品九九视频 | 看av在线| 国产精品福利在线观看 | 精品久久久久久久久久久 | 亚洲成人精 | 欧美成人精品欧美一级 | 日韩精品在线观看一区二区三区 | 天堂色综合 | 国产成人精品在线播放 | 亚洲成人一区二区三区 | 日韩中文字幕 | 成人小视频在线观看 | 亚洲午夜精品一区二区三区他趣 | 99久久电影 | 国产欧美精品一区二区三区 | 成人一区二区三区 | 日韩在线免费视频 | 亚洲一区电影 | 日本三级日产三级国产三级 | 亚洲人免费视频 | 天堂在线中文 |