- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用 Cython 加速以下代码。从 python 导入两个参数:
processing_times:包含 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
与原始 Python 代码相比,我能够将处理速度加快 4 倍:
Just Python: 0.04114614830813535
With Cython: 0.00937230621550278
Cython is 4.390183948543561 times faster
如何在此代码中获得更好的速度提升?
我已经尝试将sequence和processing_times转换为外部的numpy数组,然后使用内存 View ,但我没有得到任何改进。
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,所以我不知道我这样做是否正确。非常感谢任何帮助。
最佳答案
大部分内容看起来都输入正确,因此您不太可能获得巨大的改进。未输入的主要内容是 sequence
和processing_times
。您应该制作这些内存 View :
def taillard_acceleration(int[:] sequence, int[:,:] processing_times, int job_inserted, int num_machines):
我知道您已经尝试过此操作,但是您还应该将其索引更改为 processing_times[i,j]
的形式(而不是 processing_times[i][j]
)。您正在做的事情会创建一个 1D 内存 View 作为临时对象,这可能会慢一些。
对于q
, e
, f
,和ms
数组:如果您愿意重新编译以更改大小,那么您现在所做的绝对没问题。如果您认为可能想在运行时更改大小,那么您应该在运行时分配它们。您可以使用malloc
但我会用:
cdef int[:,::1] e = np.zeros((501,21))
([:,::1]
告诉 Cython 该数组是二维且连续的)。像这样使用 numpy 会比 malloc
慢稍微 ,但它也更容易,而且出错的可能性也更小。如果您这样做,请将它们的索引更改为 e[i,j]
如上所述。
(看起来它们的大小确实应该是 sequency_length
乘 num_machines
所以运行时大小可能是一个好主意)
关于python - Cython:加速简单代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47963417/
c 不做边界检查。那么cython是如何检查是否编译成c的呢? %%cython --annotate cimport cython @cython.boundscheck(True) cpdef m
可以直接声明用于 Cython 构造函数? 据我了解,这是可能的: # Cython cdef int[3] li = [1, 2, 3] # C++ int[3] li = {1, 2, 3} 但
所以,如果你有一个头文件。 %%file test.h struct mystruct{ int i; int j; }; 然后你将它包装在 Cython 中: cdef extern fr
我正在构建一个独立于平台的 cython 项目,我想根据正在使用的编译器传递编译器参数。我可以猜测基于平台的编译器,或者假设它与用于 Python 的编译器相同,但不能保证匹配。通常我注入(injec
我使用诗歌构建我的 cython 包。我在所有函数和类中都有 NumPy 风格的文档字符串。我现在要做的是添加 Sphinx 自动文档并发布在 Read the Docs。 我已阅读此主题 How d
赛通 libcpp模块包含 priority_queue 的模板,这很好,除了一件事:我不能通过自定义比较器(或者,至少,我不知道如何)。 我需要这个,因为我需要 priority_queue做一个a
以下代码定义了一个简单的 Cython 函数(为方便起见,使用 Ipython 魔法)。 %load_ext cython %%cython def f(float x, float y=2):
我正在尝试使用 cython 进行复数计算。在示例代码中,我想计算复数的复指数函数。问题是我不知道如何将我的整数乘以虚数单位。python的虚数单位1.0j乘以cython执行时报错。 这是我的代码:
在这里停留在一些基本的 Cython 上 - 在 Cython 中定义字符串数组的规范且有效的方法是什么? 具体来说,我想定义一个定长常量数组char . (请注意,此时我不想引入 NumPy。) 在
是否有可能,如果是,如何确定 Cython 中整数数据类型的大小(以位为单位)? 我正在尝试做这样的事情,以获得整数大小: cdef WORD_BITS = 0 IF sizeof(unsigned
我只是想打印 cython 变量的地址,但我无法绕过错误消息: cdef int myvar print &myvar 抛出 Cannot convert 'int *' to Python obje
我有一个 C 头文件,它在宏中定义了一个函数。我需要从 Cython 调用它。有没有办法在 Cython 中使用宏并使其完全扩展?我已经有了 C 类型的参数。 我尝试像使用函数一样使用 cdef,我认
令人惊讶的是,我似乎找不到通过名称获取结构体元素的单个示例(无论是在网络上还是在 cython 示例中)。 所以我收到了一个指向 C 函数结构体的指针,并且想要一一访问这些元素并将它们重新打包到 py
我尝试围绕 C++ 库编写一个 Cython 包装器 http://primesieve.org/ 它包装了一个函数count。到目前为止,它可以正确安装 python setup.py instal
我正在尝试将 cython 模块 data.pyx 导入另一个 cython 模块 user.pyx。一切都编译得很好,但是当我尝试在 python 模块中调用 user.pyx 时,我收到错误“Im
更新:内存 View 获胜。Cython 使用类型化内存 View :0.0253449 特别感谢 lothario,他指出了几个关键的变化。 荒谬。当然现在的问题是,似乎不能对它们做太多算术(加法和
我有一个使用 memoryview 数组的 cython 模块,即... double[:,:] foo 我想使用多处理并行运行这个模块。但是我得到了错误: PicklingError: Can't
我正在尝试使用 Cython 加速 PEP 484 类型的 python 脚本。我想保持一些语义和可读性。 之前,我有一个 Flags = int def difference(f1: Flags,
这个问题已经有答案了: Collapse multiple submodules to one Cython extension (5 个回答) 已关闭 3 年前。 我在一个包中有多个 .py 文件
我已经能够在我的 .pyx 脚本上使用 cython 在 linux 上创建一个 .so 文件。我也可以成功地在我的 python 解释器上进行导入。 我的问题是如何在不使用 cython 的情况下将
我是一名优秀的程序员,十分优秀!