问题描述
我正在对Erlang的lists:reverse
内置函数(BIF)进行性能分析,以查看其随输入大小的扩展程度。更具体地说,我尝试过:
1> X = lists:seq(1,1000000).
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29|...]
2> timer:tc(lists,reverse,[X]).
{57737,[1000000,999999,999998,999997,999996,999995,999994,999993,999992,999991,999990,999989,999988,999987,999986,999985,999984,999983,999982,999981,999980,999979,999978,999977,999976,999975,999974|...]}
3> timer:tc(lists,[X]).
{46896,999974|...]}
4> Y = lists:seq(1,10000000).
[1,29|...]
5> timer:tc(lists,[Y]).
{434079,[10000000,9999999,9999998,9999997,9999996,9999995,9999994,9999993,9999992,9999991,9999990,9999989,9999988,9999987,9999986,9999985,9999984,9999983,9999982,9999981,9999980,9999979,9999978,9999977,9999976,9999975,9999974|...]}
6> timer:tc(lists,[Y]).
{214173,9999974|...]}
好的,到目前为止,似乎反向BIF相对于输入在大约线性时间内缩放(例如,将输入的大小乘以10,并且所花费的时间也增加10倍)。在纯Erlang中这是有意义的,因为我们将使用诸如tail递归之类的东西来反转列表。我想即使是用C语言实现的BIF,用于反转的算法似乎列表也是一样的(也许是因为列表只是以Erlang表示的方式?)。
现在,我想将它与另一种语言进行比较-也许是我已经使用的另一种动态类型的语言。因此,我在Python中尝试了类似的事情-非常明确地注意使用实际列表而不是生成器,我预计该生成器会在此测试中对Python的性能产生积极影响,从而给它带来不公平的优势。
import time
ms_conv_factor = 10**6
def profile(func,*args):
start = time.time()
func(args)
end = time.time()
elapsed_seconds = end - start
print(elapsed_seconds * ms_conv_factor,flush=True)
x = list([i for i in range(0,1000000)])
y = list([i for i in range(0,10000000)])
z = list([i for i in range(0,100000000)])
def f(m):
return m[::-1]
def g(m):
return reversed(m)
if __name__ == "__main__":
print("All done loading the lists,starting now.",flush=True)
print("f:")
profile(f,x)
profile(f,y)
print("")
profile(f,z)
print("")
print("g:")
profile(g,x)
profile(g,y)
print("")
profile(g,z)
这似乎表明函数加载并运行一次后,输入的长度没有变化,并且反转时间非常快-约0.7µs。
确切结果:
All done loading the lists,starting now.
f:
1.430511474609375
0.7152557373046875
0.7152557373046875
0.2384185791015625
0.476837158203125
g:
1.9073486328125
0.7152557373046875
0.2384185791015625
0.2384185791015625
0.476837158203125
我的第一个天真的猜测是python可能能够识别反向构造并创建诸如反向迭代器之类的东西并返回(Python可以正确使用引用?也许是在这里使用某种优化方法)。但是我认为该理论没有意义,因为原始列表和返回的列表并不相同(更改一个列表不应更改另一个列表)。
所以我的问题是:
- 我的配置文件技术是否有缺陷?我编写测试时是否偏爱一种语言?
- 在Erlang与Python中实现列表及其反向操作有何不同,从而使这种情况(Python的运行速度更快)成为可能?
(感谢您的时间)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)