timeit如何受列表文本长度的影响?

2024-04-20 09:04:36 发布

您现在位置:Python中文网/ 问答频道 /正文

更新:显然,我只是在计时Python读取列表的速度。不过,这并不能真正改变我的问题。你知道吗

所以,前几天我读了this post,想比较一下速度。我刚接触熊猫,所以每当我看到有机会做一些适度有趣的事情时,我都会欣然接受。不管怎样,我最初只是用100个数字来测试这个,我想这足以满足我和熊猫玩耍的渴望。但这张图是这样的:

list to string conversion 0-99

请注意,有3个不同的运行。这些跑步是按顺序进行的,但它们在同一个两点上都有一个尖峰。斑点大约是28和64个。所以我最初的想法是它和字节有关,特别是4。可能第一个字节包含关于它是一个列表的附加信息,然后下一个字节是所有数据,之后每4个字节会导致一个速度峰值,这有点合理。所以我需要用更多的数字来测试。所以我创建了一个由3组数组组成的数据帧,每个数组有1000个列表,长度从0到999不等。然后我以同样的方式对它们进行计时,即:

Run 1: 0, 1, 2, 3, ...
Run 2: 0, 1, 2, 3, ...
Run 3: 0, 1, 2, 3, ...

我希望看到的是数组中大约每32个项目就有一个显著的增加,但是没有重复出现这种模式(我确实放大并寻找尖峰):

list to string conversion 0-999

然而,你会注意到,它们在400和682之间都有很大的不同。奇怪的是,我总是在同一个地方跑一个尖峰,这使得在这张图的28点和64点上的模式更难区分。绿线真的到处都是。可耻的。你知道吗

问题:最初的两个峰值发生了什么,为什么在400和682之间的图上会变得“模糊”?我刚刚完成了对0-99集的测试,但这次对数组中的每个项进行了简单的加法,结果是完全线性的,所以我认为这与字符串有关。你知道吗

我先用其他方法进行了测试,得到了相同的结果,但是由于我加入了错误的结果,所以图形被弄乱了,所以我用这段代码在一夜之间再次运行它(这花费了很长时间),以确保时间与索引正确对齐,并且运行的顺序正确:

import statistics as s
import timeit
df = pd.DataFrame([[('run_%s' % str(x + 1)), r, np.random.choice(100, r).tolist()] 
                   for r in range(0, 1000) for x in range(3)], 
                  columns=['run', 'length', 'array']).sort_values(['run', 'length'])
df['time'] = df.array.apply(lambda x: s.mean(timeit.repeat(str(x))))

# Graph
ax = df.groupby(['run', 'length']).mean().unstack('run').plot(y='time')
ax.set_ylabel('Time [ns]')
ax.set_xlabel('Array Length')
ax.legend(loc=3)

如果您想查看原始数据,我也会对数据帧进行pickle处理。你知道吗


Tags: 数据rundf列表字节顺序数字数组
1条回答
网友
1楼 · 发布于 2024-04-20 09:04:36

在这里使用pandas.apply会严重地使事情过于复杂。没有必要-这只是效率低下。就用香草Python的方式:

In [3]: import timeit

In [4]: setup = "l = list(range({}))"

In [5]: test = "str(l)"

注意,timeit函数接受一个number参数,它是所有函数运行的次数。它默认为1000000,所以让我们通过使用number=100使其更合理,这样我们就不必永远等待了。。。你知道吗

In [8]: data = [timeit.repeat(test, setup.format(n), number=100) for n in range(0, 10001, 100)]

In [9]: import statistics

In [10]: mean_data = list(map(statistics.mean, data))

目视检查结果:

In [11]: mean_data
Out[11]:
[3.977467228348056e-05,
 0.0012597616684312622,
 0.002014552320664128,
 0.002637979011827459,
 0.0034494600258767605,
 0.0046060653403401375,
 0.006786816345993429,
 0.006134035007562488,
 0.006666974319765965,
 0.0073876206879504025,
 0.008359026357841989,
 0.008946725012113651,
 0.01020014965130637,
 0.0110439983351777,
 0.012085124345806738,
 0.013095536657298604,
 0.013812023680657148,
 0.014505649354153624,
 0.015109792332320163,
 0.01541508767210568,
 0.018623976677190512,
 0.018014412683745224,
 0.01837641668195526,
 0.01806374565542986,
 0.01866597666715582,
 0.021138361655175686,
 0.020885809014240902,
 0.023644315680333722,
 0.022424093661053728,
 0.024507874331902713,
 0.026360396664434422,
 0.02618172235088423,
 0.02721496132047226,
 0.026609957004742075,
 0.027632603014353663,
 0.029077719994044553,
 0.030218352350251127,
 0.03213361800105,
 0.0321545610204339,
 0.032791375007946044,
 0.033749551337677985,
 0.03418213398739075,
 0.03482868466138219,
 0.03569800598779693,
 0.035460735321976244,
 0.03980560234049335,
 0.0375820419867523,
 0.03880414469555641,
 0.03926491799453894,
 0.04079093333954612,
 0.0420664346893318,
 0.044861480011604726,
 0.045125720323994756,
 0.04562378901755437,
 0.04398221097653732,
 0.04668888701902082,
 0.04841196699999273,
 0.047662509993339576,
 0.047592316346708685,
 0.05009777001881351,
 0.04870589632385721,
 0.0532167866670837,
 0.05079756366709868,
 0.05264475334358091,
 0.05531930166762322,
 0.05283398299555605,
 0.055121281009633094,
 0.056162080339466534,
 0.05814277834724635,
 0.05694748067374652,
 0.05985202432687705,
 0.05949359833418081,
 0.05837553597909088,
 0.05975819365509475,
 0.06247356999665499,
 0.061310798317814864,
 0.06292542165222888,
 0.06698586166991542,
 0.06634997764679913,
 0.06443380867131054,
 0.06923895300133154,
 0.06685209332499653,
 0.06864909763680771,
 0.06959929631557316,
 0.06832000267847131,
 0.07180017333788176,
 0.07092387134131665,
 0.07280202202188472,
 0.07342300032420705,
 0.0745120863430202,
 0.07483605532130848,
 0.0734497313387692,
 0.0763389469939284,
 0.07811927401538317,
 0.07915793966579561,
 0.08072184936221068,
 0.08046915601395692,
 0.08565403800457716,
 0.08061318534115951,
 0.08411134833780427,
 0.0865995019945937]

在我看来,这是非常糟糕的线性。现在,pandas是一种方便的图形化方法,特别是如果您希望在matplotlib的API周围有一个方便的包装器:

In [14]: import pandas as pd

In [15]: df = pd.DataFrame({'time': mean_data, 'n':list(range(0, 10001, 100))})

In [16]: df.plot(x='n', y='time')
Out[16]: <matplotlib.axes._subplots.AxesSubplot at 0x1102a4a58>

结果如下:

enter image description here

这应该会让你在正确的轨道上,真正的时间,你一直试图时间。正如我在评论中所解释的那样,你结束的时间是:

You are timing the result of str(x) which results in some list-literal, so you are timing the interpretation of list literals, not the conversion of list->str

我只能推测你所看到的结果是什么样的模式,但这很可能取决于解释器/硬件。以下是我在机器上的发现:

In [18]: data = [timeit.repeat("{}".format(str(list(range(n)))), number=100) for n in range(0, 10001, 100)]

enter image description here

使用一个不是很大的范围:

In [23]: data = [timeit.repeat("{}".format(str(list(range(n)))), number=10000) for n in range(0, 101)]

结果是: enter image description here

我想这有点像你的。不过,也许这更适合它自己的问题。你知道吗

相关问题 更多 >