在<< Programming Erlang >>第14章中使用套接字编程,
Joe给了我们两个版本的receive_data(Socket,SoFar):
receive_data(Socket, SoFar) ->
receive
{tcp,Socket,Bin} ->
receive_data(Socket, [Bin|SoFar]);
{tcp_closed,Socket} ->
list_to_binary(reverse(SoFar))
end和
receive_data(Socket, SoFar) ->
receive
{tcp,Socket,Bin} ->
receive_data(Socket, list_to_binary([SoFar,Bin]));
{tcp_closed,Socket} ->
SoFar
end.然后乔说:
后一个版本--我们正在不断地在缓冲区的末尾添加一个新的二进制文件--这需要大量的数据复制。
但我仍然不太清楚Bin\SoFar和list_to_binary(SoFar,Bin)之间的区别。
乔所说的“大量复制数据”是什么意思?
哪些功能使大量的数据处理,list_to_binary或SoFar,Bin
发布于 2014-03-14 11:59:03
我对深二郎的内部结构没有任何了解,但我的看法是:
list_to_binary([SoFar,Bin])在每次调用时都会创建一个新的二进制文件:编译器无法对其进行优化。所有数据都必须复制并组装到新分配的内存空间中。
[Bin|SoFar]只是将一个元素添加到一个列表(哪一个是好的)中,它不涉及复制数据,只是指针在移动。这是建立一个列表的正确方法,而不是一个不断增长的列表的大量副本。
发布于 2014-03-14 12:29:13
它来自于列表和二进制文件之间的区别。
列表要么是空列表,要么是由元素(头)构成的构造,或者是到列表其余部分(尾)的“链接”。在C代码中,它可以用两个指针来实现,第一个指针指向元素或零(空列表),第二个指针指向尾部:另一个指针。-我没有检查erlang库中的实现。
这意味着当您想要在接收新的数据块时创建一个新列表时,list的解决方案只是创建这个新列表的头,该列表包含对新接收的数据(Bin)的引用,以及对以前接收的数据(SoFar) Bin SoFar的引用。这是可能的,因为所有变量都是不可变的。
二进制文件没有内部结构,因此如果要使用list_to_binary(Bin,SoFar)将单个二进制(第二个解决方案)接收的全部数据增加,编译器将分配一个新的内存空间并复制其中的所有数据。不可变数据的相同原则使其无法优化执行。
https://stackoverflow.com/questions/22402123
复制相似问题