Java、PHP、Python、Erlang、Golang 千萬級記憶體資料插入、查詢效能對比
測試環境:
centos 6.3 64bit
php 7.2
java 1.86
python 3.4.8
Erlang/OTP 19 [erts-8.1]
golang 1.9.2
至強2.5G 4核 x 2
8 G記憶體
146g scsi x 2 raid 0+1
測試內容:
2000萬資料,每條資料一個int id,一個string name
測試建立2000萬資料的時間速度,再在這2000萬資料中查詢100條左右,計算查詢速度。
所有的語言,搜尋資料都不寫演算法、單程序(執行緒),利用語言資料型別自身的搜尋能力,避免因為演算法寫得好壞而導致的偏差
結果:
詳細結果:
測試環境:
centos 6.3 64bit
php 7.2
java 1.86
python 3.4.8
至強2.5G 4核 x 2
8 G記憶體
146g scsi x 2 raid 0+1
測試內容:
2000萬資料,每條資料一個int id,一個string name
測試建立2000萬資料的時間速度,再在這2000萬資料中查詢100條左右,計算查詢速度。
所有的語言,搜尋資料都不寫演算法,利用語言資料型別自身的搜尋能力,避免因為演算法寫得好壞而導致的偏差
=================================================================================================
php swoole.table,2000萬資料的結果
=================================================================================================
[
======================
Create total use 55.112974882126
Real create time 30.919550180435
======================
Real create speed 662364.10 q/s
======================
Real Row count 19250719
======================
======================
116 use 0.000099
Query Speed 1172383.77 q/s
Avg query time use 0.000001 s
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 30836 98.8 62.9 5447960 5152052 pts/1 S+ 09:30 1:00 php7 swoole_table_test.php
root 30838 0.0 0.0 106108 1156 pts/1 S+ 09:31 0:00 sh -c ps aux|grep php
root 30840 0.0 0.0 103336 864 pts/1 S+ 09:31 0:00 grep php
=================================================================================================
php 原生陣列,8G記憶體不夠用,下面是1000萬資料的結果
=================================================================================================
[[email protected] swoole_test]# php7 php_array_test.php
======================
Create total use 25.156011104584
Real create time 13.448930025101
======================
Real create speed 761398.86 q/s
======================
Real Row count 9626186
======================
======================
123 use 0.000109
Query Speed 1128882.70 q/s
Avg query time use 0.000001 s
root 30863 96.9 55.7 5089968 4568848 pts/1 S+ 09:38 0:25 php7 php_array_test.php
root 30865 2.0 0.0 106108 1156 pts/1 S+ 09:39 0:00 sh -c ps aux|grep php
root 30867 0.0 0.0 103336 864 pts/1 S+ 09:39 0:00 grep php
=================================================================================================
java hashtable做資料儲存,資料用string[]
=================================================================================================
[[email protected] swoole_test]# ./java_run.sh java_string_arr_data_test.jar
======================
Create total use 205.590419
Real create time 45.750554
======================
Real create speed 420792.19 q/s
======================
Real Row count 19251476
======================
106 use 0.000149
Query Speed 711409.40 q/s
Avg query time use 0.00000141 s
======================
[[email protected] ~]$ ps aux|grep java|test
root 31326 0.0 0.0 106108 1208 pts/1 S+ 10:55 0:00 /bin/sh ./java_run.sh java_string_arr_data_test.jar
root 31327 472 78.2 10972376 6409940 pts/1 Sl+ 10:55 14:47 java -Xms512m -Xmx7012m -XX:PermSize=512m -XX:MaxPermSize=2048m -jar java_string_arr_data_test.jar
=================================================================================================
java hashtable做資料儲存,資料用class,結果浮動比較大,測試機並沒有什麼負載,列三組結果
=================================================================================================
[[email protected] swoole_test]# ./java_run.sh java_class_arr_data_test.jar
======================
Create total use 184.592579
Real create time 59.947452
======================
Real create speed 321138.54 q/s
======================
Real Row count 19251437
======================
105 use 0.000166
Query Speed 632530.12 q/s
Avg query time use 0.00000158 s
======================
[[email protected] ~]$ ps aux|grep java|grep test
root 31537 0.0 0.0 106108 1208 pts/1 S+ 11:08 0:00 /bin/sh ./java_run.sh java_class_arr_data_test.jar
root 31538 455 71.0 10972372 5815956 pts/1 Sl+ 11:08 13:39 java -Xms512m -Xmx7012m -XX:PermSize=512m -XX:MaxPermSize=2048m -jar java_class_arr_data_test.jar
======================
Create total use 157.527681
Real create time 47.727919
======================
Real create speed 403343.00 q/s
======================
Real Row count 19250722
======================
104 use 0.000153
Query Speed 679738.56 q/s
Avg query time use 0.00000147 s
======================
======================
Create total use 183.524738
Real create time 65.922781
======================
Real create speed 292012.09 q/s
======================
Real Row count 19250249
======================
101 use 0.000149
Query Speed 677852.35 q/s
Avg query time use 0.00000148 s
======================
[[email protected] ~]$ ps aux|grep java|grep test
root 31684 0.0 0.0 106108 1208 pts/1 S+ 11:30 0:00 /bin/sh ./java_run.sh java_class_arr_data_test.jar
root 31685 456 70.8 10972372 5800084 pts/1 Sl+ 11:30 14:00 java -Xms512m -Xmx7012m -XX:PermSize=512m -XX:MaxPermSize=2048m -jar java_class_arr_data_test.jar
=================================================================================================
python Dictionary做資料儲存,資料用tuple ,
=================================================================================================
[[email protected] swoole_test]# python python_dict_turple_test.py
======================
Create total use 687.165280
Real create time 206.128578
======================
Real create speed 99355.461494 q/s
======================
Real Row count 20480000
======================
98 use 0.001468
Query Speed 66757.49 q/s
Avg query time use 0.000015 s
======================
root 32433 99.8 55.2 4678148 4526036 pts/1 S+ 13:52 11:27 python python_dict_turple_test.py
root 32470 8.0 0.0 106108 1156 pts/1 S+ 14:03 0:00 sh -c ps aux|grep python|grep test
======================
python 500萬資料測試
======================
Create total use 169.645076
Real create time 51.137284
======================
Real create speed 97776.017976 q/s
======================
Real Row count 5000000
======================
111 use 0.001677
Query Speed 66189.62 q/s
Avg query time use 0.000015 s
======================
=================================================================================================
erlang erlang是一門反人類的語言,除了變數不可變而外,各種怪異的語法符號,完全是為你難以掌握而設計的。
=================================================================================================
記憶體佔得多的時候7.5G,虛擬記憶體還佔17G,但有時候又會突然下降,一會兒又漲上去了。
[[email protected] swoole_test]# ./run_erl.sh
本次測試的是1024萬資料
資料儲存程序dict,資料Tuple,因為不知道如何取得程序字典資料量,所以每次增加之前都進行了檢查。
執行插入800萬條之後,程式“卡住”好幾分鐘,
======================
Create total use 659.250587
Real create time 25.764429
======================
Real create speed 373587.747666 q/s
======================
Real Row count 9625275
======================
90 use 0.031466
Query Speed 2860.230090 q/s
Avg query time use 0.000349 s
======================
第二次測試同樣是卡住了,我想原因在於查詢,因為每次插入都查詢是否存在,而查詢又特別慢:
為什麼查詢慢呢,我想是因為erlang所謂變數不變造成的:因為變數不變,但資料要變,所以會大量的申請新空間來存放新的值,這會消耗大量的記憶體和cpu,
所以erlang用了巨量的虛擬記憶體,所以查詢速度,自然慢了。
======================
Create total use 1973.850796
Real create time 28.166692
======================
Real create speed 341735.834652 q/s
======================
Real Row count 9625568
======================
95 use 1.233148
Query Speed 77.038604 q/s
Avg query time use 0.012981 s
======================
root 25053 73.9 94.0 17911268 7703228 pts/1 Sl+ 14:54 4:10 /usr/local/lib/erlang/erts-8.1/bin/beam.smp -- -root /usr/local/lib/erlang -progname erl -- -home /root -- -noshell -s erlang_list_dict_test test -s init stop
======================
Erlang&程序字典+map 500萬資料測試
======================
======================
Create total use 159.719715
Real create time 15.408685
======================
Real create speed 324492.323647 q/s
======================
Real Row count 5000000
======================
99 use 0.000510
Query Speed 194117.647059 q/s
Avg query time use 0.000005 s
======================
root 14961 99.3 39.2 6771772 3213308 pts/0 Sl+ 17:13 2:39 /usr/local/lib/erlang/erts-8.1/bin/beam.smp -- -root /usr/local/lib/erlang -progname erl -- -home /root -- -noshell -s erlang_list_dict_test test -s init stop
========================================
erlang 儲存改為ets,500萬資料測試結果。
======================
Create total use 138.476614
Real create time 36.483799
======================
Real create speed 137047.131523 q/s
======================
Real Row count 5000000
======================
99 use 0.000488
Query Speed 202868.852459 q/s
Avg query time use 0.000005 s
======================
root 16029 99.1 33.0 5783256 2706632 pts/0 Sl+ 18:11 2:19 /usr/local/lib/erlang/erts-8.1/bin/beam.smp -- -root /usr/local/lib/erlang -progname erl -- -home /root -- -noshell -s erlang_list_dict_test test -s init stop
======================
Create total use 2070.049225
Real create time 747.731820
======================
Real create speed 13694.749543 q/s
======================
Real Row count 10240000
======================
101 use 0.061205
Query Speed 1650.191978 q/s
Avg query time use 0.000606 s
======================
root 27899 83.9 94.7 16092260 7762780 pts/1 Sl+ 18:40 5:36 /usr/local/lib/erlang/erts-8.1/bin/beam.smp -- -root /usr/local/lib/erlang -progname erl -- -home /root -- -noshell -s erlang_list_dict_test test -s init stop
root 27899 35.0 92.6 24427200 7586016 pts/1 Sl+ 18:40 6:13 /usr/local/lib/erlang/erts-8.1/bin/beam.smp -- -root /usr/local/lib/erlang -progname erl -- -home /root -- -noshell -s erlang_list_dict_test test -s init stop
==========================================
erlang ets 500萬資料結果
root 15044 99.3 33.1 5783512 2712636 pts/0 Sl+ 17:21 2:18 /usr/local/lib/erlang/erts-8.1/bin/beam.smp -- -root /usr/local/lib/erlang -progname erl -- -home /root -- -noshell -s erlang_list_dict_test test -s init stop
=================================================================================================
golang map儲存所有資料,單條資料是struct,
=================================================================================================
[[email protected] swoole_test]# go build golang_data_benchmark.go
[[email protected] swoole_test]# ./golang_data_benchmark
cpu只使用50%左右
======================
Create total use 192.196030
Real create time 67.784217
======================
Real create speed 301417.627826 q/s
======================
Real Row count 20431358
======================
95 use 0.000355
Query Speed 267601.665547 q/s
Avg query time use 0.000004 s
======================
root 14226 125 42.0 3729248 3446672 pts/0 Sl+ 15:25 4:05 ./golang_data_benchmark
貼2個qq群:31068495(Cocos&Unity&Java&C程式招聘),95303036(PHPer&頁遊&Mobile&U3D 2D)
測試原始碼:
Go的直接帖下面了:
package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
"time"
"io"
"crypto/rand"
"encoding/binary"
"bytes"
"runtime"
)
const row_num = 20480000
const max_rd = row_num * 8
type data struct {
id uint32
name string
}
func Md5(str string)(string){
//fmt.Println("Md5 str=", str)
h := md5.New()
h.Write([]byte(str))
return hex.EncodeToString(h.Sum(nil))
}
func BytesToInt(b []byte) uint32 {
bytesBuffer := bytes.NewBuffer(b)
var tmp uint32
binary.Read(bytesBuffer, binary.BigEndian, &tmp)
return tmp
}
func getRd() uint32 {
b := make([]byte, 4)
if _, err := io.ReadFull(rand.Reader, b); err != nil {
return 0
}
return BytesToInt(b) //+uint32(mrand.Int31n(max_rd))
}
func GetTimestampInMicro() float64{
mil := int64(time.Now().UnixNano() / 1000)
return float64(mil)/1000000
}
func main() {
//runtime.GOMAXPROCS(8)
runtime.GOMAXPROCS(runtime.NumCPU())
//mrand.Seed(time.Now().UnixNano())
datas := make(map[string]data)
search_key_sli:=make([]string , 0)
var rd uint32
//var value data
fmt.Println("Rd_max=", max_rd, ", row_num=", row_num)
var count_repeat, real_count int = 0, 0
var real_create_ts,_start_ts, time_use float64 = 0 , 0 , 0
start_ts := GetTimestampInMicro()
for i := 0; i < row_num; i++ {
var d data
var name string
rd = getRd() //rand.Int31n(max_rd) + 1
//fmt.Println("Rand=" , rd)
d.id = rd
str := fmt.Sprint(rd)
name = Md5(str)
d.name = name
_, ok := datas[name]
if ok{
count_repeat ++
}else{
_start_ts = GetTimestampInMicro()
datas[name] = d
real_create_ts += GetTimestampInMicro() - _start_ts
real_count ++
}
if rd % row_num <100{
search_key_sli=append(search_key_sli, name)
}
}
time_use = GetTimestampInMicro() - start_ts
//real_count := len(datas)
fmt.Println("Repeat=", count_repeat)
fmt.Println("Real count by len=", len(datas))
fmt.Printf("======================\n")
fmt.Printf("Create total use %.6f\n", time_use)
fmt.Printf("Real create time %.6f\n", real_create_ts)
fmt.Printf("======================\n")
fmt.Printf("Real create speed %.6f q/s\n", float64(real_count)/real_create_ts)
fmt.Printf("======================\n")
fmt.Printf("Real Row count %d\n", real_count)
fmt.Printf("======================\n")
var item string
start_ts = GetTimestampInMicro()
for _, item = range search_key_sli {
fmt.Printf("=> name= %s\n", datas[item].name)
}
time_use = GetTimestampInMicro() - start_ts
fmt.Printf("%d use %.6f\n", len(search_key_sli), time_use)
fmt.Printf("Query Speed %.6f q/s\n", float64(len(search_key_sli))/time_use)
fmt.Printf("Avg query time use %.6f s\n", time_use/float64(len(search_key_sli)))
fmt.Printf("======================\n")
time.Sleep(time.Duration(120)*time.Second)
}