Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.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
Python Cython:加快简单代码的速度_Python_Cython - Fatal编程技术网

Python Cython:加快简单代码的速度

Python Cython:加快简单代码的速度,python,cython,Python,Cython,我正试图用Cython加速下面的代码。从python导入两个参数: 处理时间:列出500个列表,每个列表包含20个整数(500x20) 序列:列出500个整数 cimport cython @cython.boundscheck(False) @cython.wraparound(False) cpdef taillard_acceleration(sequence, processing_times, int job_inserted, int num_machines): # S

我正试图用Cython加速下面的代码。从python导入两个参数:

处理时间:列出500个列表,每个列表包含20个整数(500x20)

序列:列出500个整数

cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)

cpdef taillard_acceleration(sequence, processing_times, int job_inserted, int num_machines):

    # Static arrays - number of jobs limited to 500 jobs and 20 machines
    cdef int e[501][21]
    cdef int q[501][21]
    cdef int f[501][21]
    cdef int ms[501]

    # Variables
    cdef int sequence_length, best_makespan, best_position
    cdef int i, j, iq, jq, tmp

    # Initialize some values
    sequence_length = len(sequence)
    iq = sequence_length + 1


    for i in range(1, sequence_length + 2):
        if i < sequence_length + 1:
            e[i][0] = 0

            # Q index I
            iq = iq - 1
            q[iq][num_machines + 1] = 0

        f[i][0] = 0
        jq = num_machines + 1


        for j in range(1, num_machines + 1):
            if i == 1:
                e[0][j] = 0
                q[sequence_length + 1][num_machines + 1 - j] = 0
            if i < sequence_length + 1:
                # Q Index J
                jq = jq - 1

                if e[i][j - 1] > e[i - 1][j]:
                    e[i][j] = e[i][j - 1] + processing_times[sequence[i - 1]-1][j-1]
                else:
                    e[i][j] = e[i - 1][j] + processing_times[sequence[i - 1]-1][j-1]

                if q[iq][jq + 1] > q[iq + 1][jq]:
                    q[iq][jq] = q[iq][jq + 1] + processing_times[sequence[iq - 1]-1][jq-1]
                else:
                    q[iq][jq] = q[iq + 1][jq] + processing_times[sequence[iq - 1]-1][jq-1]

            # f(ij) = max {f(i, j-1), e(i-1, j)}
            if f[i][j - 1] > e[i - 1][j]:
                f[i][j] = f[i][j - 1] + processing_times[job_inserted-1][j-1]
            else:
                f[i][j] = e[i - 1][j] + processing_times[job_inserted-1][j-1]


    # Makespam - job k in position i
    best_makespan = 0
    best_position = 0
    for i in range(1, sequence_length + 2):
        ms[i] = 0
        for j in range(1, num_machines + 1):
            tmp = f[i][j] + q[i][j]
            if tmp > ms[i]:
                ms[i] = tmp
        # Check best insertion position
        if ms[i] < best_makespan or best_makespan == 0:
            best_makespan = ms[i]
            best_position = i


    return best_position, best_makespan
如何在这段代码中获得更好的速度提升

我已经尝试在外部将序列和处理时间转换为numpy数组,然后使用内存视图,但这方面没有改进

cpdef taillard_acceleration(sequence_np, processing_times_np, int job_inserted, int num_machines):

    # memory view
    cdef int [:, :] processing_times = processing_times_np
    cdef int [:] sequence = sequence_np

我还应该为q、e、f、ms阵列使用malloc吗?第一次使用Cython,所以我不知道我做的是否正确。非常感谢您提供的任何帮助。

大多数帮助看起来都是正确键入的,因此您不太可能获得巨大的改进。没有键入的主要内容是
序列
处理时间
。您应该制作以下记忆视图:

def taillard_acceleration(int[:] sequence, int[:,:] processing_times, int job_inserted, int num_machines):
我知道您已经尝试过了,但是您也应该将其索引更改为
处理次数[I,j]
(而不是
处理次数[I][j]
)。您正在执行的操作将创建一个1D memoryview作为临时对象,这可能会稍微慢一点


对于
q
e
f
ms
数组:如果您愿意重新编译以更改大小,那么您现在所做的是绝对正确的。如果您认为可能需要在运行时更改大小,那么应该在运行时分配它们。您可以使用
malloc
,但我会使用:

cdef int[:,::1] e = np.zeros((501,21))
[:,::1]
告诉Cython数组是二维的且连续的)。像这样使用numpy会比
malloc
稍微慢一点,但它也更容易,并且不太可能出错。如果您这样做,则将其索引更改为如上所述的
e[i,j]


(看起来它们的大小应该是
sequency\u length
by
num\u machines
,所以运行时大小可能是个好主意)

这类问题可能更适合这里的主题(尽管在codereview上也是主题)。对于Cython问题,人们通常在这里比在codereview上有更好的机会得到体面的答案,因此我们通常不建议将其移动。alias
f[i]
因此您不必访问内部循环中的元素。@DavidW:我不同意这两点。“如果您正在以下领域中的项目中寻找关于特定工作代码的反馈…性能…那么您的位置是正确的!”(CodeReview/on topic)。此外,有一个相当好的机会,其中一些用户知道所有关于税收的信息,能够写出一个体面的税收问题的答案。这并不是一个好的提问地方。@usr2564301我同意这是codereview的主题。我在SO帮助中没有看到任何东西,可以说它不在这里的主题上(即,它是“一个特定的编程问题”)。我不建议移动它的唯一原因是,代码审查时Cython的问题数量非常少,所以很少有Cython专家定期检查它-这是一种自我永存的问题…内存视图的问题是它们的索引。只需更改为处理_次[i,j]即可使速度提高近3倍。Cython现在比Python中的原始代码快11倍。谢谢
cdef int[:,::1] e = np.zeros((501,21))