【问题标题】:Runtime generation and compilation of Cython functionsCython 函数的运行时生成和编译
【发布时间】:2018-04-20 12:25:36
【问题描述】:

一个简短的版本

是否有一种简单的方法可以在运行时将 Cython 函数编译为字符串?

详细说明

我有一个参数化的子程序,例如

cdef algo(x, params)
  • 该算法执行的操作相对较少,但调用非常频繁;
  • params 在编译时未知,但在开始时已知(例如通过配置设置)并且在程序的整个生命周期内固定
  • algo 可以针对特定的params 进行算法优化(优化超出了编译器的能力),但是,可能优化的algo 数量非常多。

换句话说,有一个函数接收params 并为这些params 生成algo 的快速实现代码:

def meta_algo(params):
  <meta magic>
  return code_of_super_fast_algo

问题是如何编译和导入meta_algo的输出定义的函数?

一个例子

假设您有一组固定的字符串ys。 对于给定的另一个字符串x,您希望使用来自ys 的每个字符串计算x 的最大公共前缀的长度,并将其作为整数数组返回。一个简单的参考实现:

def max_prefix(x, ys):
  result = []
  for i, y in enumerate(ys):
    j = 0
    while x[j] == y[j]:
      j++

    result[i] = j

  return result

例如,如果知道ys 的字符串彼此严重相交,则可以轻松计算比较树,但使用任何树数据结构都会引入不希望的开销。相反,人们可以在一系列ifs 中“内联”这个树结构并生成高效的代码。

对于ys = ['aaa', 'aab', 'baa'],可能会得到:

cdef max_prefix(str x):
  if x[0] == 'a':
    if x[1] != 'a':
      return [1, 1, 0]
    if x[2] == 'a':
      return [3, 2, 0]
    elif x[2] == 'b':
      return [2, 3, 0]
    else:
      return [2, 2, 0]
  elif ...:
    ...

【问题讨论】:

  • Cython.inline 几乎可以做你想做的事,但它不会生成cdef 函数。

标签: python metaprogramming cython


【解决方案1】:

在深入挖掘 Cython 的胆量后,我发现了以下池请求:

https://github.com/cython/cython/pull/555

它提供了我想要的确切功能:

code = """
cpdef int plus(int a, int b):
  return a + b
"""

module = cython_inline_module(code)
plus = getattr(module, 'plus')

assert plus(1, 2) == 3

【讨论】:

  • PR 还没有合并。事实上,它在 2016 年就已经开放,所以不太可能很快合并。您是否找到了属于核心 Cython 的替代品?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-12
  • 1970-01-01
相关资源
最近更新 更多