iolist跟list有什么区别?

本文详细解析了Erlang中iolist与list的区别,并通过源码展示iolist的定义和作用,特别强调了iolist在向port发送数据时提高效率的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看到erlang-china.org上有个帖子在问这个问题
[quote]一直不太明白iolist,跟list到底有什么区别?请各位大侠指教。。[/quote]

我翻看了半天erlang的文档也没写的太明白,所以就看看源码:
erts/emulator/beam/utils.c


3015int io_list_len(Eterm obj)
3016{
3017 Eterm* objp;
3018 Sint len = 0;
3019 DECLARE_ESTACK(s);
3020 goto L_again;
3021
3022 while (!ESTACK_ISEMPTY(s)) {
3023 obj = ESTACK_POP(s);
3024 L_again:
3025 if (is_list(obj)) {
3026 L_iter_list:
3027 objp = list_val(obj);
3028 /* Head */
3029 obj = CAR(objp);
3030 if (is_byte(obj)) {
3031 len++;
3032 } else if (is_binary(obj) && binary_bitsize(obj) == 0) {
3033 len += binary_size(obj);
3034 } else if (is_list(obj)) {
3035 ESTACK_PUSH(s, CDR(objp));
3036 goto L_iter_list; /* on head */
3037 } else if (is_not_nil(obj)) {
3038 goto L_type_error;
3039 }
3040 /* Tail */
3041 obj = CDR(objp);
3042 if (is_list(obj))
3043 goto L_iter_list; /* on tail */
3044 else if (is_binary(obj) && binary_bitsize(obj) == 0) {
3045 len += binary_size(obj);
3046 } else if (is_not_nil(obj)) {
3047 goto L_type_error;
3048 }
3049 } else if (is_binary(obj) && binary_bitsize(obj) == 0) { /* Tail was binary */
3050 len += binary_size(obj);
3051 } else if (is_not_nil(obj)) {
3052 goto L_type_error;
3053 }
3054 }
3055
3056 DESTROY_ESTACK(s);
3057 return len;
3058
3059 L_type_error:
3060 DESTROY_ESTACK(s);
3061 return -1;
3062}


从源码可以看出来iolist是这样的定义的:
1. []
2. binary
3. 列表, 每个元素是int(0-255)或者binary或者iolist.
其中binary是指 bitsize % 8 == 0 .
int 是0-255


root@ubuntu:/usr/src/otp# erl
Erlang R13B04 (erts-5.7.5) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.5 (abort with ^G)
2> iolist_size(<<>>).
0
3> iolist_size(<<1:1>>).
** exception error: bad argument
in function iolist_size/1
called as iolist_size(<<1:1>>)
4> iolist_size(<<1:8>>).
1
5> iolist_size([]).
0
6> iolist_size(<<1,2>>).
2
7> iolist_size([1,2]).
2
8> iolist_size([1,2, <<1,2>>]).
4
9> iolist_size([1,2, <<1,2>>, [2]]).
5
10> iolist_size([1,2, <<1,2>>, [2]]).
5
11> iolist_size([<<1:1>>]).
** exception error: bad argument
in function iolist_size/1
called as iolist_size([<<1:1>>])
12>


Iolist的作用是用于往port送数据的时候.由于底层的系统调用如writev支持向量写, 就避免了无谓的iolist_to_binary这样的扁平话操作, 避免了内存拷贝,极大的提高了效率.
建议多用.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值