erlang ets写入mysql_Erlang 进程字典 VS ETS
Erlang中常用数据存储存储和传递方式并不多,一般来说用起来也就
函数传递,ETS,进程字典,理论上来说函数传递是没有存储和取出的过程而直接传递数据,所以它应该是最快的,gen_server里面的State就是通过一个loop函数传递的,所以将运行过程中的状态放到这里,使用的消耗最小。而ETS和进程字典,一般常识来看会认为进程字典会更快一些(或者很多)。
以上都是经验分析,让我们用代码来评估一下Erlang的数据操作的实际效率,以后coding的时候也心中有数。
Erlang代码:
%%%
-------------------------------------------------------------------
%%% Author : Mizzling
%%% Description :
%%% 测试ETS/进程字典的存取效率
%%% Created : 2013-11-4
%%%
-------------------------------------------------------------------
-module(data_speed_test).
%%
====================================================================
%% API functions
%%
====================================================================
-export([raw_trans/1]).
-export([create_ets/0, insert_ets/2, lookup_ets/1,
delete_ets/1]).
-export([insert_mem/2, lookup_mem/1, delete_mem/1]).
-export([run_test/2]).
run_test(N, Value) ->
create_ets(),
{Time1, _} = timer:tc(?MODULE, raw_trans, [N]),
io:format("raw_transfer for ~p: ~pus, average:~pus~n", [N,
Time1, Time1/N]),
{Time2, _} = timer:tc(?MODULE, insert_ets, [N, Value]),
TrueTime2 = Time2 - Time1,
io:format("insert_ets ~p: ~pus, average:~pus~n", [N,
TrueTime2, TrueTime2/N]),
{Time3, _} = timer:tc(?MODULE, lookup_ets, [N]),
TrueTime3 = Time3 - Time1,
io:format("lookup_ets ~p: ~pus, average:~pus~n", [N,
TrueTime3, TrueTime3/N]),
{Time4, _} = timer:tc(?MODULE, delete_ets, [N]),
TrueTime4 = Time4 - Time1,
io:format("delete_ets ~p: ~pus, average:~pus~n", [N,
TrueTime4, TrueTime4/N]),
{Time5, _} = timer:tc(?MODULE, insert_mem, [N, Value]),
TrueTime5 = Time5 - Time1,
io:format("insert_mem ~p: ~pus, average:~pus~n", [N,
TrueTime5, TrueTime5/N]),
{Time6, _} = timer:tc(?MODULE, lookup_mem, [N]),
TrueTime6 = Time6 - Time1,
io:format("lookup_mem ~p: ~pus, average:~pus~n", [N,
TrueTime6, TrueTime6/N]),
{Time7, _} = timer:tc(?MODULE, delete_mem, [N]),
TrueTime7 = Time7 - Time1,
io:format("delete_mem ~p: ~pus, average:~pus~n", [N,
TrueTime7, TrueTime7/N]),
ok.
raw_trans(1) ->
ok;
raw_trans(N) ->
raw_trans(N-1).
create_ets() ->
case ets:info(speed_test) of
undefined ->
skip;
_ ->
ets:delete(speed_test)
end,
ets:new(speed_test, [named_table, public, {keypos, 1}]).
insert_ets(1, Value) ->
ets:insert(speed_test, {1, Value}),
ok;
insert_ets(N, Value) ->
ets:insert(speed_test, {N, Value}),
insert_ets(N-1, Value).
lookup_ets(1) ->
ets:lookup(speed_test, 1),
ok;
lookup_ets(N) ->
ets:lookup(speed_test, N),
lookup_ets(N-1).
delete_ets(1) ->
ets:delete(speed_test, 1),
ok;
delete_ets(N) ->
ets:delete(speed_test, N),
delete_ets(N-1).
insert_mem(1, Value) ->
put(1, Value),
ok;
insert_mem(N, Value) ->
put(N, Value),
insert_mem(N-1, Value).
lookup_mem(1) ->
get(1),
ok;
lookup_mem(N) ->
get(N),
lookup_mem(N-1).
delete_mem(1) ->
erase(1),
ok;
delete_mem(N) ->
erase(N),
delete_mem(N-1).
在自己机器上随便做了三组测试(cpu是i7-3630QM,四核2.4G,win8系统,有条件的可以在linux机器上做一下):
werl -pa ../ebin -name mizzle@127.0.0.1 -smp disabled -h
9999999
Erlang R15B01 (erts-5.9.1) [smp:8:8] [async-threads:0]
Eshell V5.9.1 (abort with ^G)
(mizzle@127.0.0.1)1>
data_speed_test:run_test(10000, 1).
raw_transfer for 10000: 0us, average:0.0us
insert_ets 10000: 0us, average:0.0us
lookup_ets 10000: 15000us, average:1.5us
delete_ets 10000: 0us, average:0.0us
insert_mem 10000: 0us, average:0.0us
lookup_mem 10000: 0us, average:0.0us
delete_mem 10000: 0us, average:0.0us
ok
(mizzle@127.0.0.1)2>
data_speed_test:run_test(10000,
dict:new()).
raw_transfer for 10000: 0us, average:0.0us
insert_ets 10000: 16000us, average:1.6us
lookup_ets 10000: 0us, average:0.0us
delete_ets 10000: 0us, average:0.0us
insert_mem 10000: 0us, average:0.0us
lookup_mem 10000: 0us, average:0.0us
delete_mem 10000: 0us, average:0.0us
ok
(mizzle@127.0.0.1)3>
(mizzle@127.0.0.1)3>
data_speed_test:run_test(10000,
lists:duplicate(10,dict:new())).
raw_transfer for 10000: 0us, average:0.0us
insert_ets 10000: 93000us, average:9.3us
lookup_ets 10000: 32000us, average:3.2us
delete_ets 10000: 15000us, average:1.5us
insert_mem 10000: 0us, average:0.0us
lookup_mem 10000: 0us, average:0.0us
delete_mem 10000: 0us, average:0.0us
ok
(mizzle@127.0.0.1)4>
data_speed_test:run_test(100000, 1).
raw_transfer for 100000: 0us, average:0.0us
insert_ets 100000: 110000us, average:1.1us
lookup_ets 100000: 62000us, average:0.62us
delete_ets 100000: 63000us, average:0.63us
insert_mem 100000: 31000us, average:0.31us
lookup_mem 100000: 0us, average:0.0us
delete_mem 100000: 16000us, average:0.16us
ok
(mizzle@127.0.0.1)5>
data_speed_test:run_test(100000,
dict:new()).
raw_transfer for 100000: 0us, average:0.0us
insert_ets 100000: 188000us, average:1.88us
lookup_ets 100000: 125000us, average:1.25us
delete_ets 100000: 78000us, average:0.78us
insert_mem 100000: 31000us, average:0.31us
lookup_mem 100000: 0us, average:0.0us
delete_mem 100000: 16000us, average:0.16us
ok
(mizzle@127.0.0.1)6>
(mizzle@127.0.0.1)6>
data_speed_test:run_test(100000,
lists:duplicate(10,dict:new())).
raw_transfer for 100000: 0us, average:0.0us
insert_ets 100000: 906000us, average:9.06us
lookup_ets 100000: 505000us, average:5.05us
delete_ets 100000: 111000us, average:1.11us
insert_mem 100000: 28000us, average:0.28us
lookup_mem 100000: 4000us, average:0.04us
delete_mem 100000: 3000us, average:0.03us
ok
(mizzle@127.0.0.1)7>
data_speed_test:run_test(1000000, dict:new()).
raw_transfer for 1000000: 31000us, average:0.031us
insert_ets 1000000: 2610000us, average:2.61us
lookup_ets 1000000: 1488000us, average:1.488us
delete_ets 1000000: 1390000us, average:1.39us
insert_mem 1000000: 359000us, average:0.359us
lookup_mem 1000000: 1000us, average:0.001us
delete_mem 1000000: 109000us, average:0.109us
ok
(mizzle@127.0.0.1)8>
data_speed_test:run_test(10000000, dict:new()).
raw_transfer for 10000000: 313000us, average:0.0313us
insert_ets 10000000: 30065000us, average:3.0065us
lookup_ets 10000000: 18927000us, average:1.8927us
delete_ets 10000000: 8653000us, average:0.8653us
insert_mem 10000000: 3918000us, average:0.3918us
lookup_mem 10000000: -3000us, average:-0.0003us
delete_mem 10000000: 1090000us, average:0.109us
ok
结论:
1、ETS的性能受数据量和单条数据影响,受数据量影响并不是特别明显;而当单条数据很大时,操作效率会明显降低。
2、进程字典的查询很快,在1千万数据时出现了负数,说明这个测试用例都并不能精确到进程字典的操作时间量级,但是写入和删除就没那么快,在us量级上,而且进程字典几乎不受单条数据大小影响。
3、正常情况下,我们要存储的数据一般在测试情况中1~dict之间,这种情况下ETS操作在微秒级,而进程字典的写入和删除操作比ETS快一个数量级,查询快N个数量级。
4、ETS的内存消耗比进程字典大,这个没有做具体的数据分析,是根据进程管理器里的内存变化来预估的,因为1亿数据时内存溢出了,所以回头关注了一下内存增长,但是没有改程序打印具体内存情况。
总体来说,ETS和进程字典都提供了非常快的速度。一般情况下,ETS的速度都够我们用了。如果对实时性要求特别高,对于查询远多于写入的场景,在进程能够承受的前提下(因为ETS可以是public的,而进程字典只能本进程查询,所以使用进程字典可能需要进程提供查询接口,这里要考虑进程收发消息),使用进程字典优化掉ETS将提供非常大的优化空间;而即使是写入和删除相对较多的话,也能够提升10倍左右。
erlang ets写入mysql_Erlang 进程字典 VS ETS相关推荐
- 《Erlang程序设计》第十五章 ETS和DETS:大数据的存储机制
第十五章 ETS和DETS:大数据的存储机制 Table of Contents 第十五章 ETS和DETS:大数据的存储机制 15.1 表的基本操作 创建和打开表 插入表 查找元组 释放表 15.2 ...
- Erlang进程字典底层实现剖析
进程字典的结构: typedef struct proc_dict {unsigned int sizeMask; // 掩码,用于计算hash值落到data的索引值unsigned int used ...
- [转]Erlang 大量写入出警报
Posts - 71 Articles - 6 Comments - 7 [集]erlang常用配置文件收集 http://www.cnblogs.com/gordonchao/archive/2 ...
- python 字典写入excel_Openpyxl – 从字典写入excel的行和列
Openpyxl – 从字典写入excel的行和列 所以我试图做的是从字典中写入现有的Excel文件: wb = load_workbook(filename='test.xlsx') ws2 = w ...
- erlang rebar 配置mysql_Erlang Rebar 使用指南之四:依赖管理
Erlang Rebar 使用指南之四:依赖管理 全文目录: 本章链接: 1 rebar依赖定义 Rebar取得和构建符合OTP/Rebar规范的项目.如果项目包含子项目,Rebar会自动递归地构建它 ...
- erlang rebar 配置mysql_Erlang打包工具rebar安装使用
Rebar--Erlang构建工具,可以方便的编译测试Erlang应用程序和发布. 一.Rebar的安装 1.在页面https://bitbucket.org/basho/rebar/download ...
- erlang rebar 配置mysql_Erlang Rebar 使用指南之一:入门篇
Erlang Rebar 使用指南之一:入门篇 全文目录: 本章原文: Rebar 是功能丰富的 Erlang 构建工具.用于Erlang/OTP项目的编译,测试,依赖管理,打包发布等.Rebar 是 ...
- python 列表写入csv_Python将字典数据写入CSV文件
# -*- coding: utf-8 -*- import os import time import csv class WriteCSV(): """定义成员变量& ...
- python字典类型写入文件_python 字典写入文件
{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...
- Erlang的散列数据结构
介绍Erlang的dict模块( dictionary),dict就是一个通过散列(hash)来存放数据的组织方式,同时dict模块还提供了完整的操作接口,类似的模块还有orddict模块.具体讲如何 ...
最新文章
- 小知识~LocalDB在IIS上如何成功配置
- 云炬WEB开发笔记 2-3git详细安装教程及下载太慢的解决办法
- 代码编译突然变缓慢问题解决办法(codeblock)
- 集训01-03 (c++实现)
- 学习Spring Boot:(二十七)Spring Boot 2.0 中使用 Actuator
- 网络IPC:套接字之套接字描述符
- tableau 集动作_在Tableau中通过添加操作,控制集并高亮显示数据
- Handbook之012:函数类别构型
- 小括号教学设计导入_丁文丽《含有小括号的混合运算》教学设计
- 在 Android 中调用二进制可执行程序(native executable )
- amos调节变量怎么画_AMOS结构方程教程,调节效应分析操作与结果的详细解读 ——【杏花开生物医药统计】...
- 手机号正则(2020年4月15日)
- html标签的message,Message 消息提示
- 基于Python实现的微信好友数据分析——抓取好友性别、位置、头像签名
- 关于iPhone X下Home Indicator(白条)的隐藏和延迟响应
- leetcode 滑动窗口1
- 大学物理实验报告2——数字示波器的使用
- LVDS接口测试工装研究
- 通过注册表删除软件自动生成的设备和驱动器
- 常见离线文件密码暴力爆破【rar,pdf】
热门文章
- c3p0-0.9.1.2.jar与c3p0-0.9.5.2.jar
- Gitlab用户角色权限Guest、Reporter、Developer、Master、Owner
- 80072745 80072efd 解决办法
- [转妙文]垃圾收集趣史
- 新增网站组网方案与解释说明 模版
- 让ADB识别未知设备...
- Linux原子操作与锁实现
- 计算机找网络共享盘快捷键,电脑共享快捷键不见了怎么办
- vs调试nuget包_NuGet包调试源码的方法
- win7搭建nas存储服务器_普通用户的低成本家庭文件服务器(伪NAS)的搭建(系统篇)...