锁定老帖子 主题:变量不是不可变
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-05-30
最后修改:2009-09-15
sf bay facory 来自Facebook的Eugene Letuchy在ppt http://www.erlang-factory.com/upload/presentations/31/EugeneLetuchy-ErlangatFacebook.pdf 里面提到: hipe_bifs Cheating single assignment ▪ Erlang is opinionated: ▪ Destructive assignment is hard because it should be ▪ hipe_bifs:bytearray_update() allows for destructive array assignment ▪ Necessary for aggregating Chat users’ presence ▪ Don’t tell anyone! 这是一个很好的绕过变量不可变的方法, 我再挖掘下google, 发现如下的文章: http://erlang.org/pipermail/erlang-questions/2007-February/025331.html Per Gustafsson <> Thu Feb 22 17:41:01 CET 2007 * Previous message: [erlang-questions] Deforesting tuple updates * Next message: [erlang-questions] Is UBF still going, or did it morph/fade? * Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] Joel Reymont wrote: > I don't think it works for floats or doubles. It's just bytes or > fixnums if I remember it correctly. > > On Feb 22, 2007, at 3:32 PM, Daniel Luna wrote: > > >>As long as the values in the array are simple terms, you can use >>hipe_bifs:bytearray/2. > > > -- > http://wagerlabs.com/ > > > > > > _______________________________________________ > erlang-questions mailing list > > http://www.erlang.org/mailman/listinfo/erlang-questions You could use this code: -module(floats). -export([new/1,update/3,sum/1, new2/1,update2/3,sum2/1, test/0]). new(N) -> hipe_bifs:bytearray(N*8,0). update(Arr,N,Float) -> <<A1,A2,A3,A4,A5,A6,A7,A8>> = <<Float/float>>, Start=N*8, hipe_bifs:bytearray_update(Arr,Start,A1), hipe_bifs:bytearray_update(Arr,Start+1,A2), hipe_bifs:bytearray_update(Arr,Start+2,A3), hipe_bifs:bytearray_update(Arr,Start+3,A4), hipe_bifs:bytearray_update(Arr,Start+4,A5), hipe_bifs:bytearray_update(Arr,Start+5,A6), hipe_bifs:bytearray_update(Arr,Start+6,A7), hipe_bifs:bytearray_update(Arr,Start+7,A8). sum(Bin) -> sum(Bin,0.0). sum(<<Float/float,Rest/binary>>, Acc) -> sum(Rest,Float+Acc); sum(<<>>,Acc) -> Acc. Performance is not that great, about 4-5 times faster updates than gb_trees for arrays of 100000 floats, and summing is slower. Per 试验下: root@yufeng-desktop:~# cat floats.erl -module(floats). -export([new/1,update/3,sum/1]). new(N) -> hipe_bifs:bytearray(N*8,0). update(Arr,N,Float) -> <<A1,A2,A3,A4,A5,A6,A7,A8>> = <<Float/float>>, Start=N*8, hipe_bifs:bytearray_update(Arr,Start,A1), hipe_bifs:bytearray_update(Arr,Start+1,A2), hipe_bifs:bytearray_update(Arr,Start+2,A3), hipe_bifs:bytearray_update(Arr,Start+3,A4), hipe_bifs:bytearray_update(Arr,Start+4,A5), hipe_bifs:bytearray_update(Arr,Start+5,A6), hipe_bifs:bytearray_update(Arr,Start+6,A7), hipe_bifs:bytearray_update(Arr,Start+7,A8). sum(Bin) -> sum(Bin,0.0). sum(<<Float/float,Rest/binary>>, Acc) -> sum(Rest,Float+Acc); sum(<<>>,Acc) -> Acc. root@yufeng-desktop:~# erl Erlang R13B01 (erts-5.7.2) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.7.2 (abort with ^G) 1> F = floats:new(5). <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,...>> 2> rp(F). <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0>> ok 3> floats:update(F, 1, 1234.00). <<0,0,0,0,0,0,0,0,64,147,72,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,...>> 4> rp(F). <<0,0,0,0,0,0,0,0,64,147,72,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0>> ok 5> floats:update(F, 2, 5678.00). <<0,0,0,0,0,0,0,0,64,147,72,0,0,0,0,0,64,182,46,0,0,0,0,0, 0,0,0,0,0,...>> 6> rp(F). <<0,0,0,0,0,0,0,0,64,147,72,0,0,0,0,0,64,182,46,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0>> ok 7> floats:sum(F). 6912.0 8> 1234+ 5678=6912. 6912 9> 恩 没问题的, 不错。 再到源码去挖掘下 ...\otp_src_R13A-0\erts\emulator\hipe\hipe_bif0.tab bif hipe_bifs:bytearray/2 bif hipe_bifs:bytearray_sub/2 bif hipe_bifs:bytearray_update/3 bif hipe_bifs:bitarray/2 bif hipe_bifs:bitarray_sub/2 bif hipe_bifs:bitarray_update/3 bif hipe_bifs:array/2 bif hipe_bifs:array_length/1 bif hipe_bifs:array_sub/2 bif hipe_bifs:array_update/3 bif hipe_bifs:ref/1 bif hipe_bifs:ref_get/1 bif hipe_bifs:ref_set/2 root@yufeng-desktop:~# erl Erlang R13B01 (erts-5.7.2) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.7.2 (abort with ^G) 1> A=hipe_bifs:array(10, []). 2135987033931617136292706780490918553627426255794015745390464377869606912860751039403868490301435 2> rp(A). 2135987033931617136292706780490918553627426255794015745390464377869606912860751039403868490301435 ok 3> hipe_bifs:array_length(A). 10 4> hipe_bifs:array_update(A, 2, 1). 2135987033931617136292706780490918553627426255794015745390464377869527684698900857852928490209275 5> 5> hipe_bifs:array_update(A, 1, atom). 2135987033931617136292706780490918553627426255794015745390464377869527684698882411121018128039931 6> hipe_bifs:array_sub(A,1). atom 7> hipe_bifs:array_sub(A,2). 1 8> R=hipe_bifs:ref(1). 31 9> hipe_bifs:ref_get(R). 1 10> hipe_bifs:ref_set(R, 10). 175 11> hipe_bifs:ref_get(R). 10 O Yeah 这些也都OK. 还有很多hipe_bifs的导出在相应的.tab文件里面,读者自己挖掘了。这样我们就可以把状态更新, 无需通过消息 或者 ets, 大大加快效率。 附上8皇后的hipe源码。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-05-30
不过除非必要 不要用这些trick 毕竟是和设计的初衷违背的东西。
|
|
返回顶楼 | |
发表时间:2009-05-30
估计这些都是所谓的脏函数
|
|
返回顶楼 | |
发表时间:2009-05-31
en 这个是追求速度 某些场合还是很好用的
|
|
返回顶楼 | |
发表时间:2009-05-31
结合const pool我们可以做出全局变量的东西 哈哈 真好用!
|
|
返回顶楼 | |
发表时间:2009-06-03
原先優美簡單的程序就是這樣一步步被crack成為復雜,難以理解,難以維護的遺產代碼的。。。
|
|
返回顶楼 | |
发表时间:2009-06-03
主要是考虑到erlang的所以状态都是在进程维护的 要改变状态 必须给进程发消息 这个开销有时候是不可承受的 比较改变一个变量的值 要做的事情太多 进程要调度2次 很吓人的。
|
|
返回顶楼 | |
发表时间:2009-11-11
以前没能理解,现在用上了,才知道好啊,老大,你的好东西太多了,哈哈/
|
|
返回顶楼 | |
发表时间:2009-11-11
whrllm 写道 以前没能理解,现在用上了,才知道好啊,老大,你的好东西太多了,哈哈/ 请吃饭喝酒泡妞吧 |
|
返回顶楼 | |
发表时间:2009-11-11
老大,请问一下,如何结合const pool使用啊?能不能提示一下啊?谢谢
|
|
返回顶楼 | |