Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用numba jit提高python脚本的性能_Python_Numba - Fatal编程技术网

使用numba jit提高python脚本的性能

使用numba jit提高python脚本的性能,python,numba,Python,Numba,我正在运行一个示例python模拟来预测加权和规则骰子。我想使用numba帮助加快脚本速度,但我收到一个错误: <timed exec>:6: NumbaWarning: Compilation is falling back to object mode WITH looplifting enabled because Function "roll" failed type inference due to: Untyped global name 'sum': cannot d

我正在运行一个示例python模拟来预测加权和规则骰子。我想使用numba帮助加快脚本速度,但我收到一个错误:

<timed exec>:6: NumbaWarning: 
Compilation is falling back to object mode WITH looplifting enabled because Function "roll" failed type inference due to: Untyped global name 'sum': cannot determine Numba type of <class 'builtin_function_or_method'>

File "<timed exec>", line 9:
<source missing, REPL/exec in use?>
:6:NumbaWarning:
编译正在退回到启用循环提升的对象模式,因为函数“roll”的类型推断失败,原因是:未类型化的全局名称“sum”:无法确定
文件“”,第9行:
这是我的原始代码:是否有其他类型的numba表达式可以替代?现在我正在使用2500卷的输入进行测试;希望将时间缩短到4秒(目前为8.5秒)

%%次
从numba导入jit
随机输入
将matplotlib.pyplot作为plt导入
进口numpy
@准时制
def辊(侧面、偏置列表):
断言len(偏差列表)=边,“输入正确的骰子边数”
数字=随机。均匀(0,和(偏差列表))
电流=0
对于i,枚举中的偏差(偏差列表):
电流+=偏置

如果数字您可以使用guvectorize加速它

%%time
from numba import guvectorize
import matplotlib.pyplot as plt
import numpy as np
import random

sides = 6
bias_list = (0.15, 0.15, 0.15, 0.15, 0.15, 0.25)

@guvectorize(["f8[:,:], uint8[:]"], "(n, k) -> (n)", nopython=True)
def roll(biases, side):
    for i in range(biases.shape[0]):
        number = random.uniform(0, np.sum(biases[i,:]))
        current = 0
        for j, bias in enumerate(biases[i,:]):
            current += bias
            if number <= current:
                side[i] = j + 1
                break

no_of_rolls = 2500
biases = np.zeros((no_of_rolls,len(bias_list)))

biases[:,] = np.array(bias_list)

normal_die = roll(biases)

print(normal_die)
%%次
从numba导入guvectorize
将matplotlib.pyplot作为plt导入
将numpy作为np导入
随机输入
边数=6
偏差列表=(0.15,0.15,0.15,0.15,0.15,0.15,0.25)
@guvectorize([“f8[:,:],uint8[:]”],“(n,k)->(n)”,nopyton=True)
def辊(偏压,侧面):
对于范围内的i(偏差。形状[0]):
数字=随机均匀(0,np.和(偏差[i,:]))
电流=0
对于j,枚举中的偏差(偏差[i,:]):
电流+=偏置
如果数字使用随机选择

重构代码

import random
import matplotlib.pyplot as plt

no_of_rolls = 2500

# weights
normal_weights = (0.167, 0.167, 0.167, 0.167, 0.167, 0.165)
bias_weights = (0.15, 0.15, 0.15, 0.15, 0.15, 0.25)

# Replaced roll function with random.choices 
# Reference: https://www.w3schools.com/python/ref_random_choices.asp
bias_rolls = random.choices(range(1, 7), weights = bias_weights, k = no_of_rolls)
normal_rolls = random.choices(range(1, 7), weights = normal_weights, k = no_of_rolls)

# Create dictionaries with same structure as posted code
weighted_die = dict(zip(range(no_of_rolls), bias_rolls))
normal_die = dict(zip(range(no_of_rolls), normal_rolls))

# Use posted plotting calls
plt.bar(*zip(*weighted_die.items()))
plt.show()
plt.bar(*zip(*normal_die.items()))
plt.show()
*Not including plotting.*
Original code: ~6 ms
Revised code:  ~2 ms
(3x improvement, but not sure why the post mentions 8 seconds to run)
性能

import random
import matplotlib.pyplot as plt

no_of_rolls = 2500

# weights
normal_weights = (0.167, 0.167, 0.167, 0.167, 0.167, 0.165)
bias_weights = (0.15, 0.15, 0.15, 0.15, 0.15, 0.25)

# Replaced roll function with random.choices 
# Reference: https://www.w3schools.com/python/ref_random_choices.asp
bias_rolls = random.choices(range(1, 7), weights = bias_weights, k = no_of_rolls)
normal_rolls = random.choices(range(1, 7), weights = normal_weights, k = no_of_rolls)

# Create dictionaries with same structure as posted code
weighted_die = dict(zip(range(no_of_rolls), bias_rolls))
normal_die = dict(zip(range(no_of_rolls), normal_rolls))

# Use posted plotting calls
plt.bar(*zip(*weighted_die.items()))
plt.show()
plt.bar(*zip(*normal_die.items()))
plt.show()
*Not including plotting.*
Original code: ~6 ms
Revised code:  ~2 ms
(3x improvement, but not sure why the post mentions 8 seconds to run)

如果你只是想要一个更快的模拟,你可以用它来生成加权骰子和普通骰子的列表。你能给我一个例子吗?请随意使用我的代码&alter。@leewieldon——提供了一个代码示例。然而,我不明白为什么你说代码需要8.5秒才能运行。我得到了毫秒的时间(不包括绘图)。@DarrylG,谢谢!这确实提高了性能。谢谢你!我运行了你建议的代码&在我的机器上,它似乎没有给我多大的速度(实际上多了1秒)。对。我刚意识到策划要花很多时间。谢谢!这确实加快了我的代码速度。我的计算机一定不能像你的一样健壮,但不管更新帮助如何。谢谢你@Leewieldon--嗯,仍然令人惊讶,因为我的电脑是一台8岁左右的旧台式电脑,i7CPU 920@2.67GHz,存在间歇性硬件问题,所以它确实需要更换。我有一台i7CPU@1.80GHz。这就是我想象的原因:)