提高我的速度

2024-06-16 09:45:09 发布

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

我已经创建了下面的代码,它需要一系列的值, 在x和r之间生成10个数字,平均值为8000

为了尽可能地满足规范的覆盖范围,我还计算了标准差,这是一个很好的扩展度量。因此,每当一个样本集满足平均值8000的标准时,我就把它与以前的匹配进行比较,不断地选择标准偏差最高的样本(平均值总是=8000)

def node_timing(average_block_response_computational_time, min_block_response_computational_time, max_block_response_computational_time):
    sample_count = 10
    num_of_trials = 1

    # print average_block_response_computational_time
    # print min_block_response_computational_time
    # print max_block_response_computational_time

    target_sum = sample_count * average_block_response_computational_time
    samples_list = []
    curr_stdev_max = 0
    for trials in range(num_of_trials):
        samples = [0] * sample_count
        while sum(samples) != target_sum:
            samples = [rd.randint(min_block_response_computational_time, max_block_response_computational_time) for trial in range(sample_count)]
        # print ("Mean: ", st.mean(samples), "Std Dev: ", st.stdev(samples), )
        # print (samples, "\n")
        if st.stdev(samples) > curr_stdev_max:
            curr_stdev_max = st.stdev(samples)
            samples_best = samples[:]
        return samples_best[0]

我取列表中的第一个值并使用它作为计时值,但是这段代码非常慢,我需要在模拟过程中调用这段代码几千次,所以需要提高代码的效率

有人对怎么做有什么建议吗?你知道吗


Tags: sample代码timeresponsecountminblockmax
1条回答
网友
1楼 · 发布于 2024-06-16 09:45:09

为了看看我们在哪里可以得到最好的速度改进,我首先分析了您的代码。你知道吗

import cProfile
pr = cProfile.Profile()
pr.enable()
for i in range(100):
    print(node_timing(8000, 7000, 9000))
pr.disable()
pr.print_stats(sort='time')

结果的顶部显示了代码花费的大部分时间:

   23561178 function calls (23561176 primitive calls) in 10.612 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
  4502300    3.694    0.000    7.258    0.000 random.py:172(randrange)
  4502300    2.579    0.000    3.563    0.000 random.py:222(_randbelow)
  4502300    1.533    0.000    8.791    0.000 random.py:216(randint)
   450230    1.175    0.000    9.966    0.000 counter.py:19(<listcomp>)
  4608421    0.690    0.000    0.690    0.000 {method 'getrandbits' of '_random.Random' objects}
      100    0.453    0.005   10.596    0.106 counter.py:5(node_timing)
  4502300    0.294    0.000    0.294    0.000 {method 'bit_length' of 'int' objects}
   450930    0.141    0.000    0.150    0.000 {built-in method builtins.sum}
      100    0.016    0.000    0.016    0.000 {built-in method builtins.print}
      600    0.007    0.000    0.025    0.000 statistics.py:105(_sum)
     2200    0.005    0.000    0.006    0.000 fractions.py:84(__new__)
...

从这个输出中,我们可以看到我们花费了约7.5秒(10.6秒中)来生成随机数。因此,唯一能显著加快这一速度的方法就是生成更少的随机数或更快地生成它们。你没有使用加密随机数生成器,所以我没有办法让生成数字更快。但是,我们可以稍微篡改一下算法,并大幅减少需要生成的值的数量。你知道吗

与其只接受平均值为8000的样本,不如我们接受平均值为8000+-0.1%的样本(那么我们的样本平均值为7992到8008)?由于有点不精确,我们可以大大加快算法的速度。我将while条件替换为:

while abs(sum(samples) - target_sum) > epsilon

其中epsilon = target_sum * 0.001。然后我再次运行脚本,得到了更好的探查器编号。你知道吗

         232439 function calls (232437 primitive calls) in 0.163 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      100    0.032    0.000    0.032    0.000 {built-in method builtins.print}
    31550    0.026    0.000    0.053    0.000 random.py:172(randrange)
    31550    0.019    0.000    0.027    0.000 random.py:222(_randbelow)
    31550    0.011    0.000    0.064    0.000 random.py:216(randint)
     4696    0.010    0.000    0.013    0.000 fractions.py:84(__new__)
     3155    0.008    0.000    0.073    0.000 counter.py:19(<listcomp>)
      600    0.008    0.000    0.039    0.000 statistics.py:105(_sum)
      100    0.006    0.000    0.131    0.001 counter.py:4(node_timing)
    32293    0.005    0.000    0.005    0.000 {method 'getrandbits' of '_random.Random' objects}
     1848    0.004    0.000    0.009    0.000 fractions.py:401(_add)

允许平均值高达目标值的0.1%,将调用randint的次数减少了100倍。当然,代码运行速度也快了100倍(现在大部分时间都花在打印控制台上)。你知道吗

相关问题 更多 >