- 浏览: 982303 次
- 性别:
- 来自: 广州
最新评论
-
qingchuwudi:
有用,非常感谢!
erlang进程的优先级 -
zfjdiamond:
你好 这条命令 在那里输入??
你们有yum 我有LuaRocks -
simsunny22:
这个是在linux下运行的吧,在window下怎么运行escr ...
escript的高级特性 -
mozhenghua:
http://www.erlang.org/doc/apps/ ...
mnesia 分布协调的几个细节 -
fxltsbl:
A new record of 108000 HTTP req ...
Haproxy 1.4-dev2: barrier of 100k HTTP req/s crossed
主题:erlang静态数据查询方式的一种构想 http://www.iteye.com/topic/461367
解决这个问题有2种方式:
1. 函数匹配
2. per module constant pool
针对这个问题我做了个试验, 构建一个atom->int的查询。
yu-fengdemacbook-2:~ yufeng$ cat t.erl
-module(t).
-export([start/1, start/2]).
start([A1, A2])->
start(list_to_integer(atom_to_list(A1)), A2).
start(N, Meth)->
Start = erlang:now(),
dotimes(N, case Meth of m->fun dict_lookup/1; f->fun fun_lookup/1 end),
Stop = erlang:now(),
erlang:display( N / time_diff(Start, Stop)).
dotimes(0, _) ->
done;
dotimes(N, F) ->
F(N),
dotimes(N - 1, F).
time_diff({A1,A2,A3}, {B1,B2,B3}) ->
(B1 - A1) * 1000000 + (B2 - A2) + (B3 - A3) / 1000000.0 .
dict_lookup(I) ->
{ok, I} = dict:find(list_to_atom("x" ++ integer_to_list(I)), h1:get_dict()) .
fun_lookup(I) ->
I = h2:lookup(list_to_atom("x" ++ integer_to_list(I))).
echo "done."yu-fengdemacbook-2:~ yufeng$ cat make_dict
#!/opt/local/bin/escript
main([A])->
N = list_to_integer(A),
L = [{list_to_atom("x" ++ integer_to_list(X)), X} || X<-lists:seq(1, N)],
D = dict:from_list(L),
io:format("-module(h1).~n-export([get_dict/0]).~nget_dict()->~n",[]),
erlang:display(D),
io:format(".~n"),
ok.
yu-fengdemacbook-2:~ yufeng$ cat make_fun
#!/opt/local/bin/escript
main([A])->
N = list_to_integer(A),
io:format("-module(h2).~n-export([lookup/1]).~n",[]),
[io:format("lookup(~p)->~p;~n",[list_to_atom("x" ++ integer_to_list(X)), X]) || X<-lists:seq(1, N)],
io:format("lookup(_)->err.~n", []),
ok.
yu-fengdemacbook-2:~ yufeng$ head h1.erl
-module(h1).
-export([get_dict/0]).
get_dict()->
{dict,100,20,32,16,100,60,{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},{{[[x10|10],[x30|30],[x50|50],[x70|70],[x90|90]],[[x11|11],[x31|31],[x51|51],[x71|71],[x91|91]],[[x12|12],[x32|32],[x52|52],[x72|72],[x92|92]],[[x13|13],[x33|33],[x53|53],[x73|73],[x93|93]],[[x4|4],[x14|14],[x24|24],[x34|34],[x44|44],[x54|54],[x64|64],[x74|74],[x84|84],[x94|94]],[[x5|5],[x15|15],[x25|25],[x35|35],[x45|45],[x55|55],[x65|65],[x75|75],[x85|85],[x95|95]],[[x6|6],[x16|16],[x26|26],[x36|36],[x46|46],[x56|56],[x66|66],[x76|76],[x86|86],[x96|96]],[[x7|7],[x17|17],[x27|27],[x37|37],[x47|47],[x57|57],[x67|67],[x77|77],[x87|87],[x97|97]],[[x8|8],[x18|18],[x28|28],[x38|38],[x48|48],[x58|58],[x68|68],[x78|78],[x88|88],[x98|98]],[[x9|9],[x19|19],[x29|29],[x39|39],[x49|49],[x59|59],[x69|69],[x79|79],[x89|89],[x99|99]],[],[],[],[],[],[]},{[[x20|20],[x40|40],[x60|60],[x80|80],[x100|100]],[[x1|1],[x21|21],[x41|41],[x61|61],[x81|81]],[[x2|2],[x22|22],[x42|42],[x62|62],[x82|82]],[[x3|3],[x23|23],[x43|43],[x63|63],[x83|83]],[],[],[],[],[],[],[],[],[],[],[],[]}}}
.
yu-fengdemacbook-2:~ yufeng$ head h2.erl
-module(h2).
-export([lookup/1]).
lookup(x1)->1;
lookup(x2)->2;
lookup(x3)->3;
lookup(x4)->4;
lookup(x5)->5;
lookup(x6)->6;
lookup(x7)->7;
lookup(x8)->8;
yu-fengdemacbook-2:~ yufeng$ cat test.sh
#!/bin/bash
#OPT=+native
OPT=
echo "build $1..."
echo "make h1..."
./make_dict $1 >h1.erl
echo "make h2..."
./make_fun $1 >h2.erl
echo "compile h1..."
erlc $OPT h1.erl
echo "compile h2..."
erlc $OPT h2.erl
echo "compile t..."
erlc $OPT t.erl
echo "running..."
echo "map..."
erl -s t start $1 m -noshell -s erlang halt
echo "fun..."
erl -s t start $1 f -noshell -s erlang halt
yu-fengdemacbook-2:~ yufeng$ ./test.sh 10000
build 10000...
make h1...
make h2...
compile h1...
compile h2...
compile t...
running...
map...
2.767323e+05
fun...
2.656819e+05
done.
在10000条记录的情况下 每个查询几个us, 速度不是很快.
结果发现 函数和constant pool在处理上上差不多快的。在实践中根据需要采用把。
解释的太好了
解决这个问题有2种方式:
1. 函数匹配
2. per module constant pool
针对这个问题我做了个试验, 构建一个atom->int的查询。
yu-fengdemacbook-2:~ yufeng$ cat t.erl
-module(t).
-export([start/1, start/2]).
start([A1, A2])->
start(list_to_integer(atom_to_list(A1)), A2).
start(N, Meth)->
Start = erlang:now(),
dotimes(N, case Meth of m->fun dict_lookup/1; f->fun fun_lookup/1 end),
Stop = erlang:now(),
erlang:display( N / time_diff(Start, Stop)).
dotimes(0, _) ->
done;
dotimes(N, F) ->
F(N),
dotimes(N - 1, F).
time_diff({A1,A2,A3}, {B1,B2,B3}) ->
(B1 - A1) * 1000000 + (B2 - A2) + (B3 - A3) / 1000000.0 .
dict_lookup(I) ->
{ok, I} = dict:find(list_to_atom("x" ++ integer_to_list(I)), h1:get_dict()) .
fun_lookup(I) ->
I = h2:lookup(list_to_atom("x" ++ integer_to_list(I))).
echo "done."yu-fengdemacbook-2:~ yufeng$ cat make_dict
#!/opt/local/bin/escript
main([A])->
N = list_to_integer(A),
L = [{list_to_atom("x" ++ integer_to_list(X)), X} || X<-lists:seq(1, N)],
D = dict:from_list(L),
io:format("-module(h1).~n-export([get_dict/0]).~nget_dict()->~n",[]),
erlang:display(D),
io:format(".~n"),
ok.
yu-fengdemacbook-2:~ yufeng$ cat make_fun
#!/opt/local/bin/escript
main([A])->
N = list_to_integer(A),
io:format("-module(h2).~n-export([lookup/1]).~n",[]),
[io:format("lookup(~p)->~p;~n",[list_to_atom("x" ++ integer_to_list(X)), X]) || X<-lists:seq(1, N)],
io:format("lookup(_)->err.~n", []),
ok.
yu-fengdemacbook-2:~ yufeng$ head h1.erl
-module(h1).
-export([get_dict/0]).
get_dict()->
{dict,100,20,32,16,100,60,{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},{{[[x10|10],[x30|30],[x50|50],[x70|70],[x90|90]],[[x11|11],[x31|31],[x51|51],[x71|71],[x91|91]],[[x12|12],[x32|32],[x52|52],[x72|72],[x92|92]],[[x13|13],[x33|33],[x53|53],[x73|73],[x93|93]],[[x4|4],[x14|14],[x24|24],[x34|34],[x44|44],[x54|54],[x64|64],[x74|74],[x84|84],[x94|94]],[[x5|5],[x15|15],[x25|25],[x35|35],[x45|45],[x55|55],[x65|65],[x75|75],[x85|85],[x95|95]],[[x6|6],[x16|16],[x26|26],[x36|36],[x46|46],[x56|56],[x66|66],[x76|76],[x86|86],[x96|96]],[[x7|7],[x17|17],[x27|27],[x37|37],[x47|47],[x57|57],[x67|67],[x77|77],[x87|87],[x97|97]],[[x8|8],[x18|18],[x28|28],[x38|38],[x48|48],[x58|58],[x68|68],[x78|78],[x88|88],[x98|98]],[[x9|9],[x19|19],[x29|29],[x39|39],[x49|49],[x59|59],[x69|69],[x79|79],[x89|89],[x99|99]],[],[],[],[],[],[]},{[[x20|20],[x40|40],[x60|60],[x80|80],[x100|100]],[[x1|1],[x21|21],[x41|41],[x61|61],[x81|81]],[[x2|2],[x22|22],[x42|42],[x62|62],[x82|82]],[[x3|3],[x23|23],[x43|43],[x63|63],[x83|83]],[],[],[],[],[],[],[],[],[],[],[],[]}}}
.
yu-fengdemacbook-2:~ yufeng$ head h2.erl
-module(h2).
-export([lookup/1]).
lookup(x1)->1;
lookup(x2)->2;
lookup(x3)->3;
lookup(x4)->4;
lookup(x5)->5;
lookup(x6)->6;
lookup(x7)->7;
lookup(x8)->8;
yu-fengdemacbook-2:~ yufeng$ cat test.sh
#!/bin/bash
#OPT=+native
OPT=
echo "build $1..."
echo "make h1..."
./make_dict $1 >h1.erl
echo "make h2..."
./make_fun $1 >h2.erl
echo "compile h1..."
erlc $OPT h1.erl
echo "compile h2..."
erlc $OPT h2.erl
echo "compile t..."
erlc $OPT t.erl
echo "running..."
echo "map..."
erl -s t start $1 m -noshell -s erlang halt
echo "fun..."
erl -s t start $1 f -noshell -s erlang halt
yu-fengdemacbook-2:~ yufeng$ ./test.sh 10000
build 10000...
make h1...
make h2...
compile h1...
compile h2...
compile t...
running...
map...
2.767323e+05
fun...
2.656819e+05
done.
在10000条记录的情况下 每个查询几个us, 速度不是很快.
结果发现 函数和constant pool在处理上上差不多快的。在实践中根据需要采用把。
评论
13 楼
whaosoft
2009-09-16
谢谢,受教啦
12 楼
litaocheng
2009-09-14
mryufeng 写道
谁说dict的复杂度是N, 它的实现是个hash表, 它的复杂度是最后桶的seg的大小 + 常数。
ets用的是读写锁 如果是同一个调度器上的process,那么根据读写锁的futex实现 这个都在用户空间裁决,速度是飞快的,无什么太大的开销。 但是如果你有很多cpu 进程在不同的调度器上(不同的os线程) 那么涉及到内核裁决 速度就慢很多。
ets用的是读写锁 如果是同一个调度器上的process,那么根据读写锁的futex实现 这个都在用户空间裁决,速度是飞快的,无什么太大的开销。 但是如果你有很多cpu 进程在不同的调度器上(不同的os线程) 那么涉及到内核裁决 速度就慢很多。
解释的太好了
11 楼
mryufeng
2009-09-14
今天仔细看了下 函数匹配 原理是 把key收集在一起 在opcode i_select_val里面2分查找
汇编码:
{select_val,{x,0},
{f,7},
{list,[{integer,4},
{f,3},
{integer,3},
{f,4},
{integer,2},
{f,5},
{integer,1},
{f,6}]}}.
beam_emu.c:
OpCase(i_select_val_sfI):
GetArg1(0, tmp_arg1);
do_binary_search:
怪不得这么快。
汇编码:
{select_val,{x,0},
{f,7},
{list,[{integer,4},
{f,3},
{integer,3},
{f,4},
{integer,2},
{f,5},
{integer,1},
{f,6}]}}.
beam_emu.c:
OpCase(i_select_val_sfI):
GetArg1(0, tmp_arg1);
do_binary_search:
怪不得这么快。
10 楼
xvyu
2009-09-05
多谢指点
这么说在多核的cpu上,常量字典的表现应该优于ets
回头我尝试下
这么说在多核的cpu上,常量字典的表现应该优于ets
回头我尝试下
9 楼
mryufeng
2009-09-05
谁说dict的复杂度是N, 它的实现是个hash表, 它的复杂度是最后桶的seg的大小 + 常数。
ets用的是读写锁 如果是同一个调度器上的process,那么根据读写锁的futex实现 这个都在用户空间裁决,速度是飞快的,无什么太大的开销。 但是如果你有很多cpu 进程在不同的调度器上(不同的os线程) 那么涉及到内核裁决 速度就慢很多。
ets用的是读写锁 如果是同一个调度器上的process,那么根据读写锁的futex实现 这个都在用户空间裁决,速度是飞快的,无什么太大的开销。 但是如果你有很多cpu 进程在不同的调度器上(不同的os线程) 那么涉及到内核裁决 速度就慢很多。
8 楼
xvyu
2009-09-05
看这个结构,dict的时间复杂度应该是N,而gb_trees的时间复杂度是logN,大数据量的情况下差别会很明显
不太清楚ets的锁机制如何运作,有很多进程,比方100个,同时读,会不会有影响
不太清楚ets的锁机制如何运作,有很多进程,比方100个,同时读,会不会有影响
7 楼
mryufeng
2009-09-05
这2种方式都不会触发GC操作,所以还是值得尝试的。。。
6 楼
mryufeng
2009-09-05
我这里demo的是一种方法 至于用gb_trees dict 还是其他的数据 结构 不都是一样的吗 只是数据组织的方式不同而已。
5 楼
xvyu
2009-09-05
以前测试过
用gb_trees比dict快一些
用gb_trees比dict快一些
4 楼
mryufeng
2009-09-05
那个dict的tuple是代码生成的 不是我写的哦
3 楼
darkdestiny
2009-09-05
直接用一个大tuple来写dict,太高级了点。
写一个dict相关的tuple格式说明就好了,manual上好像没有
写一个dict相关的tuple格式说明就好了,manual上好像没有
2 楼
xvyu
2009-09-05
十分感谢mryufeng的解答
在http://mryufeng.iteye.com/blog/435855这篇文章里
ets测试的结果也是us级,这样说常量池和函数匹配的意义不大了
在http://mryufeng.iteye.com/blog/435855这篇文章里
ets测试的结果也是us级,这样说常量池和函数匹配的意义不大了
1 楼
mryufeng
2009-09-05
#!/opt/local/bin/escript 的路径 根据需要改下
发表评论
-
OTP R14A今天发布了
2010-06-17 14:36 2677以下是这次发布的亮点,没有太大的性能改进, 主要是修理了很多B ... -
R14A实现了EEP31,添加了binary模块
2010-05-21 15:15 3030Erlang的binary数据结构非常强大,而且偏向底层,在作 ... -
如何查看节点的可用句柄数目和已用句柄数
2010-04-08 03:31 4814很多同学在使用erlang的过程中, 碰到了很奇怪的问题, 后 ... -
获取Erlang系统信息的代码片段
2010-04-06 21:49 3475从lib/megaco/src/tcp/megaco_tcp_ ... -
iolist跟list有什么区别?
2010-04-06 20:30 6529看到erlang-china.org上有个 ... -
erlang:send_after和erlang:start_timer的使用解释
2010-04-06 18:31 8386前段时间arksea 同学提出这个问题, 因为文档里面写的很不 ... -
Latest news from the Erlang/OTP team at Ericsson 2010
2010-04-05 19:23 2013参考Talk http://www.erlang-factor ... -
对try 异常 运行的疑问,为什么出现两种结果
2010-04-05 19:22 2842郎咸武<langxianzhe@163.com> ... -
Erlang ERTS Async基础设施
2010-03-19 00:03 2517其实Erts的Async做的很不错的, 相当的完备, 性能又高 ... -
CloudI 0.0.9 Released, A Cloud as an Interface
2010-03-09 22:32 2476基于Erlang的云平台 看了下代码 质量还是不错的 完成了不 ... -
Memory matters - even in Erlang (再次说明了了解内存如何工作的必要性)
2010-03-09 20:26 3439原文地址:http://www.lshift.net/blog ... -
Some simple examples of using Erlang’s XPath implementation
2010-03-08 23:30 2050原文地址 http://www.lshift.net/blog ... -
lcnt 环境搭建
2010-02-26 16:19 2614抄书:otp_doc_html_R13B04/lib/tool ... -
Erlang强大的代码重构工具 tidier
2010-02-25 16:22 2486Jan 29, 2010 We are very happy ... -
[Feb 24 2010] Erlang/OTP R13B04 has been released
2010-02-25 00:31 1387Erlang/OTP R13B04 has been rele ... -
R13B04 Installation
2010-01-28 10:28 1390R13B04后erlang的源码编译为了考虑移植性,就改变了编 ... -
Running tests
2010-01-19 14:51 1486R13B03以后 OTP的模块加入了大量的测试模块,这些模块都 ... -
R13B04在细化Binary heap
2010-01-14 15:11 1508从github otp的更新日志可以清楚的看到otp R13B ... -
R13B03 binary vheap有助减少binary内存压力
2009-11-29 16:07 1668R13B03 binary vheap有助减少binary内存 ... -
erl_nif 扩展erlang的另外一种方法
2009-11-26 01:02 3218我们知道扩展erl有2种方法, driver和port. 这2 ...
相关推荐
虽然MySQL不是Erlang原生的存储解决方案,但其强大的SQL查询能力和成熟的社区支持使其在处理复杂查询和大规模数据时表现出色。通过Erlang与MySQL的集成,开发者可以利用两者的优点,构建混合型的存储解决方案。 ...
学习erlang的时候尝试编写的小例子,使用post方式发送json数据来进行http请求,希望能帮到大家~
### Erlang实战IP查询服务知识点解析 #### 一、项目背景与目标 - **项目名称**: Erlang实战IP查询服务 - **项目目的**: 该项目旨在通过开发一个具体的实例——基于Erlang语言的IP地理位置查询服务,来展示Erlang...
- **模式匹配**:Erlang的模式匹配功能允许在函数定义中使用模式来匹配和解构数据结构,简化了代码编写。 - **OTP(开放电信平台)**:Erlang OTP是一套库和设计原则,提供了构建可靠系统的框架,包括Mnesia数据库...
**Erlang编程:Introducing Erlang** Erlang是一种函数式编程语言,由爱立信在1986年开发,主要用于构建高可用性、容错性和并发性的分布式系统。"Introducing Erlang"是Simon St. Laurent撰写的一本入门级教程,...
3. **过程和模块**:Erlang的组织方式,包括如何定义和调用函数,以及模块的使用。 4. **错误调试**:Erlang的错误处理机制,如shell的使用、日志和调试工具。 5. **REPL(Read-Eval-Print Loop)**:Erlang shell...
在Erlang中,Record提供了一种方便的方式来定义和访问具有固定字段的数据类型。 在Erlang中,Records是由一个特殊的语法创建的,形如`#record_name{field1 = value1, field2 = value2, ...}`。Record_name是记录的...
3. **Erlang数据类型和API**:介绍CNode API,包括如何在C中表示和操作Erlang的数据类型(如整数、原子、列表等),以及如何调用Erlang函数和处理返回结果。 4. **进程通信**:阐述如何在CNode中创建Erlang进程,...
Erlang的字典数据结构通常比其他语言的哈希表更快,因为它优化了并发访问和内存管理。 接下来是Java,它以其跨平台能力和丰富的库而闻名。"java_class_arr_data_test.jar"和"java_string_arr_data_test.jar"可能是...
2. **数据传输**:Erlang 进程通过端口发送二进制数据到外部程序,外部程序处理后返回结果,数据通过端口返回到 Erlang 进程。Erlang 使用 `port_command/2` 发送数据,`port_recv/2` 接收数据。 3. **同步通信**:...
然而,ETS虽然提供了一种原生的查询方式,将数据库操作无缝融入语言之中,但在性能方面存在局限性,特别是对于那些对性能有极高要求且逻辑相对简单的系统。相比之下,进程字典作为另一种key-value体系,不仅能够满足...
标题中的“erlang test 生成 dets”表明我们要讨论的...总之,Erlang的DETs提供了一种简单而高效的方式来处理持久化数据。通过理解和掌握DETs的使用,开发者可以在Erlang项目中实现可靠的、可扩展的数据存储解决方案。
1. **函数式编程**:Erlang基于函数式编程范式,强调无副作用的纯函数,以及通过数据不可变性来简化并发处理。在Erlang中,程序是由一系列相互独立的函数构成的,它们可以并行执行,提高了系统的性能。 2. **并发与...
- 文章通常会包含一个简单的Rust NIF实现,例如计算两个整数的和,展示如何在Rust和Erlang之间传递数据。 - 也会演示如何在Erlang模块中注册和调用这个NIF。 6. **编译与加载**: - 编译Rust代码为动态库,并将...
Erlang是一种高级编程语言,特别适用于并发、分布式和实时系统。它由Ericsson公司开发,主要用于构建高可用性、容错性和可扩展性的软实时系统。Erlang的25.0版本是该语言的一个更新,针对Windows操作系统进行了优化...
5. **处理结果**:Erlang驱动将MySQL的查询结果转换为Erlang的数据结构,如列表或元组,以便于进一步处理。你需要遍历这些结果并根据需要进行操作。 6. **事务处理**:如果需要确保一组SQL操作的原子性,可以使用...
`dialyzer_emakefile`和`Emakefile`是Erlang的Dialyzer工具配置文件,Dialyzer是一个静态分析工具,用于检查代码中的错误和潜在问题,提高代码质量。`version.txt`则记录了项目的版本信息,这对于追踪代码的迭代和...
Erlang/OTP 26.2.1,Erlang,OTP,26.2.1
编程+Erlang.pdf可能会详细介绍Erlang的基础语法、数据类型、过程和模块等概念。 2. **并发编程**:Erlang的并发模型是其独特之处。它通过轻量级进程(Lightweight Processes, LWP)实现并发,进程间通信(Inter-...
此“Erlang-OTP-API 离线查询英文全手册”是Erlang OTP的官方文档,包含了所有API的详细信息,是学习和开发Erlang OTP应用的重要资源。手册内容广泛,包括了以下几个核心部分: 1. **模块和函数**:手册详细列出了...