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条左右,计算查询速度。
所有的语言,搜索数据都不写算法、单进程(线程),利用语言数据类型自身的搜索能力,避免因为算法写得好坏而导致的偏差

 

结果:

Java、PHP、Python、Erlang、Golang 千万级内存数据插入、查询性能对比_第1张图片

Java、PHP、Python、Erlang、Golang 千万级内存数据插入、查询性能对比_第2张图片

详细结果:

测试环境:
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万数据的结果
=================================================================================================
[root@lein swoole_test]# php7 swoole_table_test.php 
======================
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万数据的结果
=================================================================================================
[root@lein 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[]
=================================================================================================
[root@lein 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
======================
[lein@lein ~]$ 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,结果浮动比较大,测试机并没有什么负载,列三组结果
=================================================================================================
[root@lein 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
======================
[lein@lein ~]$ 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
======================


[lein@lein ~]$ 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 ,
=================================================================================================
[root@lein 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,但有时候又会突然下降,一会儿又涨上去了。

[root@lein 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,
=================================================================================================
[root@lein swoole_test]# go build golang_data_benchmark.go
[root@lein 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)

测试源码:

https://download.csdn.net/download/leinchu/10667773

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)
}

 

你可能感兴趣的:(Java、PHP、Python、Erlang、Golang 千万级内存数据插入、查询性能对比)