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相关推荐

  1. 《Erlang程序设计》第十五章 ETS和DETS:大数据的存储机制

    第十五章 ETS和DETS:大数据的存储机制 Table of Contents 第十五章 ETS和DETS:大数据的存储机制 15.1 表的基本操作 创建和打开表 插入表 查找元组 释放表 15.2 ...

  2. Erlang进程字典底层实现剖析

    进程字典的结构: typedef struct proc_dict {unsigned int sizeMask; // 掩码,用于计算hash值落到data的索引值unsigned int used ...

  3. [转]Erlang 大量写入出警报

    Posts - 71  Articles - 6  Comments - 7 [集]erlang常用配置文件收集 http://www.cnblogs.com/gordonchao/archive/2 ...

  4. python 字典写入excel_Openpyxl – 从字典写入excel的行和列

    Openpyxl – 从字典写入excel的行和列 所以我试图做的是从字典中写入现有的Excel文件: wb = load_workbook(filename='test.xlsx') ws2 = w ...

  5. erlang rebar 配置mysql_Erlang Rebar 使用指南之四:依赖管理

    Erlang Rebar 使用指南之四:依赖管理 全文目录: 本章链接: 1 rebar依赖定义 Rebar取得和构建符合OTP/Rebar规范的项目.如果项目包含子项目,Rebar会自动递归地构建它 ...

  6. erlang rebar 配置mysql_Erlang打包工具rebar安装使用

    Rebar--Erlang构建工具,可以方便的编译测试Erlang应用程序和发布. 一.Rebar的安装 1.在页面https://bitbucket.org/basho/rebar/download ...

  7. erlang rebar 配置mysql_Erlang Rebar 使用指南之一:入门篇

    Erlang Rebar 使用指南之一:入门篇 全文目录: 本章原文: Rebar 是功能丰富的 Erlang 构建工具.用于Erlang/OTP项目的编译,测试,依赖管理,打包发布等.Rebar 是 ...

  8. python 列表写入csv_Python将字典数据写入CSV文件

    # -*- coding: utf-8 -*- import os import time import csv class WriteCSV(): """定义成员变量& ...

  9. python字典类型写入文件_python 字典写入文件

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  10. Erlang的散列数据结构

    介绍Erlang的dict模块( dictionary),dict就是一个通过散列(hash)来存放数据的组织方式,同时dict模块还提供了完整的操作接口,类似的模块还有orddict模块.具体讲如何 ...

最新文章

  1. 小知识~LocalDB在IIS上如何成功配置
  2. 云炬WEB开发笔记 2-3git详细安装教程及下载太慢的解决办法
  3. 代码编译突然变缓慢问题解决办法(codeblock)
  4. 集训01-03 (c++实现)
  5. 学习Spring Boot:(二十七)Spring Boot 2.0 中使用 Actuator
  6. 网络IPC:套接字之套接字描述符
  7. tableau 集动作_在Tableau中通过添加操作,控制集并高亮显示数据
  8. Handbook之012:函数类别构型
  9. 小括号教学设计导入_丁文丽《含有小括号的混合运算》教学设计
  10. 在 Android 中调用二进制可执行程序(native executable )
  11. amos调节变量怎么画_AMOS结构方程教程,调节效应分析操作与结果的详细解读 ——【杏花开生物医药统计】...
  12. 手机号正则(2020年4月15日)
  13. html标签的message,Message 消息提示
  14. 基于Python实现的微信好友数据分析——抓取好友性别、位置、头像签名
  15. 关于iPhone X下Home Indicator(白条)的隐藏和延迟响应
  16. leetcode 滑动窗口1
  17. 大学物理实验报告2——数字示波器的使用
  18. LVDS接口测试工装研究
  19. 通过注册表删除软件自动生成的设备和驱动器
  20. 常见离线文件密码暴力爆破【rar,pdf】

热门文章

  1. c3p0-0.9.1.2.jar与c3p0-0.9.5.2.jar
  2. Gitlab用户角色权限Guest、Reporter、Developer、Master、Owner
  3. 80072745 80072efd 解决办法
  4. [转妙文]垃圾收集趣史
  5. 新增网站组网方案与解释说明 模版
  6. 让ADB识别未知设备...
  7. Linux原子操作与锁实现
  8. 计算机找网络共享盘快捷键,电脑共享快捷键不见了怎么办
  9. vs调试nuget包_NuGet包调试源码的方法
  10. win7搭建nas存储服务器_普通用户的低成本家庭文件服务器(伪NAS)的搭建(系统篇)...