这段代码实现了sorting networks个代码,我正在try 用Numba编译它们以提高性能.然而,每个函数的编译时间都在呈指数级增长.Numba总共有大约60个函数(下面只显示了19个例子),在太阳经历红巨星inflating 之前,Numba不会完成它们的编译.

我怀疑问题存在于Numba试图在编译期间应用积极的优化标志(如-O2),从而导致过高的复杂性和处理时间.

编辑:我找到了Numba takes his optimization level from environment variable NUMBA_OPT,所以我将其设置为0

import os
os.environ["NUMBA_OPT"] = "0"

但它什么也做不了.

有没有一种方法可以让Numba简单地为这些函数生成汇编代码,而不try 进一步优化? 或者其他方法来编译它?

import numba as nb
import numpy as np

# This function calculates the min and the max of his parameters.
@nb.njit(nb.types.UniTuple(nb.uint64, 2)(nb.uint64, nb.uint64),fastmath=True,inline='always')
def m(a: np.uint64, b: np.uint64) -> (np.uint64, np.uint64):
    return min(a, b), max(a, b)

@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_1(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    return a

print('Defining function 2')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_2(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[1] = m(a[0], a[1])
    return a

print('Defining function 3')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_3(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[2] = m(a[0], a[2])
    a[0], a[1] = m(a[0], a[1])
    a[1], a[2] = m(a[1], a[2])
    return a

print('Defining function 4')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_4(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[2] = m(a[0], a[2])
    a[1], a[3] = m(a[1], a[3])
    a[0], a[1] = m(a[0], a[1])
    a[2], a[3] = m(a[2], a[3])
    a[1], a[2] = m(a[1], a[2])
    return a

print('Defining function 5')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_5(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[3] = m(a[0], a[3])
    a[1], a[4] = m(a[1], a[4])
    a[0], a[2] = m(a[0], a[2])
    a[1], a[3] = m(a[1], a[3])
    a[0], a[1] = m(a[0], a[1])
    a[2], a[4] = m(a[2], a[4])
    a[1], a[2] = m(a[1], a[2])
    a[3], a[4] = m(a[3], a[4])
    a[2], a[3] = m(a[2], a[3])
    return a

print('Defining function 6')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_6(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[5] = m(a[0], a[5])
    a[1], a[3] = m(a[1], a[3])
    a[2], a[4] = m(a[2], a[4])
    a[1], a[2] = m(a[1], a[2])
    a[3], a[4] = m(a[3], a[4])
    a[0], a[3] = m(a[0], a[3])
    a[2], a[5] = m(a[2], a[5])
    a[0], a[1] = m(a[0], a[1])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[5] = m(a[4], a[5])
    a[1], a[2] = m(a[1], a[2])
    a[3], a[4] = m(a[3], a[4])
    return a

print('Defining function 7')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_7(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[6] = m(a[0], a[6])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[5] = m(a[4], a[5])
    a[0], a[2] = m(a[0], a[2])
    a[1], a[4] = m(a[1], a[4])
    a[3], a[6] = m(a[3], a[6])
    a[0], a[1] = m(a[0], a[1])
    a[2], a[5] = m(a[2], a[5])
    a[3], a[4] = m(a[3], a[4])
    a[1], a[2] = m(a[1], a[2])
    a[4], a[6] = m(a[4], a[6])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[5] = m(a[4], a[5])
    a[1], a[2] = m(a[1], a[2])
    a[3], a[4] = m(a[3], a[4])
    a[5], a[6] = m(a[5], a[6])
    return a

print('Defining function 8')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_8(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[2] = m(a[0], a[2])
    a[1], a[3] = m(a[1], a[3])
    a[4], a[6] = m(a[4], a[6])
    a[5], a[7] = m(a[5], a[7])
    a[0], a[4] = m(a[0], a[4])
    a[1], a[5] = m(a[1], a[5])
    a[2], a[6] = m(a[2], a[6])
    a[3], a[7] = m(a[3], a[7])
    a[0], a[1] = m(a[0], a[1])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[5] = m(a[4], a[5])
    a[6], a[7] = m(a[6], a[7])
    a[2], a[4] = m(a[2], a[4])
    a[3], a[5] = m(a[3], a[5])
    a[1], a[4] = m(a[1], a[4])
    a[3], a[6] = m(a[3], a[6])
    a[1], a[2] = m(a[1], a[2])
    a[3], a[4] = m(a[3], a[4])
    a[5], a[6] = m(a[5], a[6])
    return a

print('Defining function 9')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_9(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[3] = m(a[0], a[3])
    a[1], a[7] = m(a[1], a[7])
    a[2], a[5] = m(a[2], a[5])
    a[4], a[8] = m(a[4], a[8])
    a[0], a[7] = m(a[0], a[7])
    a[2], a[4] = m(a[2], a[4])
    a[3], a[8] = m(a[3], a[8])
    a[5], a[6] = m(a[5], a[6])
    a[0], a[2] = m(a[0], a[2])
    a[1], a[3] = m(a[1], a[3])
    a[4], a[5] = m(a[4], a[5])
    a[7], a[8] = m(a[7], a[8])
    a[1], a[4] = m(a[1], a[4])
    a[3], a[6] = m(a[3], a[6])
    a[5], a[7] = m(a[5], a[7])
    a[0], a[1] = m(a[0], a[1])
    a[2], a[4] = m(a[2], a[4])
    a[3], a[5] = m(a[3], a[5])
    a[6], a[8] = m(a[6], a[8])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[5] = m(a[4], a[5])
    a[6], a[7] = m(a[6], a[7])
    a[1], a[2] = m(a[1], a[2])
    a[3], a[4] = m(a[3], a[4])
    a[5], a[6] = m(a[5], a[6])
    return a

print('Defining function 10')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_10(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[8] = m(a[0], a[8])
    a[1], a[9] = m(a[1], a[9])
    a[2], a[7] = m(a[2], a[7])
    a[3], a[5] = m(a[3], a[5])
    a[4], a[6] = m(a[4], a[6])
    a[0], a[2] = m(a[0], a[2])
    a[1], a[4] = m(a[1], a[4])
    a[5], a[8] = m(a[5], a[8])
    a[7], a[9] = m(a[7], a[9])
    a[0], a[3] = m(a[0], a[3])
    a[2], a[4] = m(a[2], a[4])
    a[5], a[7] = m(a[5], a[7])
    a[6], a[9] = m(a[6], a[9])
    a[0], a[1] = m(a[0], a[1])
    a[3], a[6] = m(a[3], a[6])
    a[8], a[9] = m(a[8], a[9])
    a[1], a[5] = m(a[1], a[5])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[8] = m(a[4], a[8])
    a[6], a[7] = m(a[6], a[7])
    a[1], a[2] = m(a[1], a[2])
    a[3], a[5] = m(a[3], a[5])
    a[4], a[6] = m(a[4], a[6])
    a[7], a[8] = m(a[7], a[8])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[5] = m(a[4], a[5])
    a[6], a[7] = m(a[6], a[7])
    a[3], a[4] = m(a[3], a[4])
    a[5], a[6] = m(a[5], a[6])
    return a

print('Defining function 11')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_11(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[9] = m(a[0], a[9])
    a[1], a[6] = m(a[1], a[6])
    a[2], a[4] = m(a[2], a[4])
    a[3], a[7] = m(a[3], a[7])
    a[5], a[8] = m(a[5], a[8])
    a[0], a[1] = m(a[0], a[1])
    a[3], a[5] = m(a[3], a[5])
    a[4], a[10] = m(a[4], a[10])
    a[6], a[9] = m(a[6], a[9])
    a[7], a[8] = m(a[7], a[8])
    a[1], a[3] = m(a[1], a[3])
    a[2], a[5] = m(a[2], a[5])
    a[4], a[7] = m(a[4], a[7])
    a[8], a[10] = m(a[8], a[10])
    a[0], a[4] = m(a[0], a[4])
    a[1], a[2] = m(a[1], a[2])
    a[3], a[7] = m(a[3], a[7])
    a[5], a[9] = m(a[5], a[9])
    a[6], a[8] = m(a[6], a[8])
    a[0], a[1] = m(a[0], a[1])
    a[2], a[6] = m(a[2], a[6])
    a[4], a[5] = m(a[4], a[5])
    a[7], a[8] = m(a[7], a[8])
    a[9], a[10] = m(a[9], a[10])
    a[2], a[4] = m(a[2], a[4])
    a[3], a[6] = m(a[3], a[6])
    a[5], a[7] = m(a[5], a[7])
    a[8], a[9] = m(a[8], a[9])
    a[1], a[2] = m(a[1], a[2])
    a[3], a[4] = m(a[3], a[4])
    a[5], a[6] = m(a[5], a[6])
    a[7], a[8] = m(a[7], a[8])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[5] = m(a[4], a[5])
    a[6], a[7] = m(a[6], a[7])
    return a

print('Defining function 12')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_12(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[8] = m(a[0], a[8])
    a[1], a[7] = m(a[1], a[7])
    a[2], a[6] = m(a[2], a[6])
    a[3], a[11] = m(a[3], a[11])
    a[4], a[10] = m(a[4], a[10])
    a[5], a[9] = m(a[5], a[9])
    a[0], a[1] = m(a[0], a[1])
    a[2], a[5] = m(a[2], a[5])
    a[3], a[4] = m(a[3], a[4])
    a[6], a[9] = m(a[6], a[9])
    a[7], a[8] = m(a[7], a[8])
    a[10], a[11] = m(a[10], a[11])
    a[0], a[2] = m(a[0], a[2])
    a[1], a[6] = m(a[1], a[6])
    a[5], a[10] = m(a[5], a[10])
    a[9], a[11] = m(a[9], a[11])
    a[0], a[3] = m(a[0], a[3])
    a[1], a[2] = m(a[1], a[2])
    a[4], a[6] = m(a[4], a[6])
    a[5], a[7] = m(a[5], a[7])
    a[8], a[11] = m(a[8], a[11])
    a[9], a[10] = m(a[9], a[10])
    a[1], a[4] = m(a[1], a[4])
    a[3], a[5] = m(a[3], a[5])
    a[6], a[8] = m(a[6], a[8])
    a[7], a[10] = m(a[7], a[10])
    a[1], a[3] = m(a[1], a[3])
    a[2], a[5] = m(a[2], a[5])
    a[6], a[9] = m(a[6], a[9])
    a[8], a[10] = m(a[8], a[10])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[5] = m(a[4], a[5])
    a[6], a[7] = m(a[6], a[7])
    a[8], a[9] = m(a[8], a[9])
    a[4], a[6] = m(a[4], a[6])
    a[5], a[7] = m(a[5], a[7])
    a[3], a[4] = m(a[3], a[4])
    a[5], a[6] = m(a[5], a[6])
    a[7], a[8] = m(a[7], a[8])
    return a

print('Defining function 13')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_13(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[12] = m(a[0], a[12])
    a[1], a[10] = m(a[1], a[10])
    a[2], a[9] = m(a[2], a[9])
    a[3], a[7] = m(a[3], a[7])
    a[5], a[11] = m(a[5], a[11])
    a[6], a[8] = m(a[6], a[8])
    a[1], a[6] = m(a[1], a[6])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[11] = m(a[4], a[11])
    a[7], a[9] = m(a[7], a[9])
    a[8], a[10] = m(a[8], a[10])
    a[0], a[4] = m(a[0], a[4])
    a[1], a[2] = m(a[1], a[2])
    a[3], a[6] = m(a[3], a[6])
    a[7], a[8] = m(a[7], a[8])
    a[9], a[10] = m(a[9], a[10])
    a[11], a[12] = m(a[11], a[12])
    a[4], a[6] = m(a[4], a[6])
    a[5], a[9] = m(a[5], a[9])
    a[8], a[11] = m(a[8], a[11])
    a[10], a[12] = m(a[10], a[12])
    a[0], a[5] = m(a[0], a[5])
    a[3], a[8] = m(a[3], a[8])
    a[4], a[7] = m(a[4], a[7])
    a[6], a[11] = m(a[6], a[11])
    a[9], a[10] = m(a[9], a[10])
    a[0], a[1] = m(a[0], a[1])
    a[2], a[5] = m(a[2], a[5])
    a[6], a[9] = m(a[6], a[9])
    a[7], a[8] = m(a[7], a[8])
    a[10], a[11] = m(a[10], a[11])
    a[1], a[3] = m(a[1], a[3])
    a[2], a[4] = m(a[2], a[4])
    a[5], a[6] = m(a[5], a[6])
    a[9], a[10] = m(a[9], a[10])
    a[1], a[2] = m(a[1], a[2])
    a[3], a[4] = m(a[3], a[4])
    a[5], a[7] = m(a[5], a[7])
    a[6], a[8] = m(a[6], a[8])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[5] = m(a[4], a[5])
    a[6], a[7] = m(a[6], a[7])
    a[8], a[9] = m(a[8], a[9])
    a[3], a[4] = m(a[3], a[4])
    a[5], a[6] = m(a[5], a[6])
    return a

print('Defining function 14')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_14(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[1] = m(a[0], a[1])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[5] = m(a[4], a[5])
    a[6], a[7] = m(a[6], a[7])
    a[8], a[9] = m(a[8], a[9])
    a[10], a[11] = m(a[10], a[11])
    a[12], a[13] = m(a[12], a[13])
    a[0], a[2] = m(a[0], a[2])
    a[1], a[3] = m(a[1], a[3])
    a[4], a[8] = m(a[4], a[8])
    a[5], a[9] = m(a[5], a[9])
    a[10], a[12] = m(a[10], a[12])
    a[11], a[13] = m(a[11], a[13])
    a[0], a[4] = m(a[0], a[4])
    a[1], a[2] = m(a[1], a[2])
    a[3], a[7] = m(a[3], a[7])
    a[5], a[8] = m(a[5], a[8])
    a[6], a[10] = m(a[6], a[10])
    a[9], a[13] = m(a[9], a[13])
    a[11], a[12] = m(a[11], a[12])
    a[0], a[6] = m(a[0], a[6])
    a[1], a[5] = m(a[1], a[5])
    a[3], a[9] = m(a[3], a[9])
    a[4], a[10] = m(a[4], a[10])
    a[7], a[13] = m(a[7], a[13])
    a[8], a[12] = m(a[8], a[12])
    a[2], a[10] = m(a[2], a[10])
    a[3], a[11] = m(a[3], a[11])
    a[4], a[6] = m(a[4], a[6])
    a[7], a[9] = m(a[7], a[9])
    a[1], a[3] = m(a[1], a[3])
    a[2], a[8] = m(a[2], a[8])
    a[5], a[11] = m(a[5], a[11])
    a[6], a[7] = m(a[6], a[7])
    a[10], a[12] = m(a[10], a[12])
    a[1], a[4] = m(a[1], a[4])
    a[2], a[6] = m(a[2], a[6])
    a[3], a[5] = m(a[3], a[5])
    a[7], a[11] = m(a[7], a[11])
    a[8], a[10] = m(a[8], a[10])
    a[9], a[12] = m(a[9], a[12])
    a[2], a[4] = m(a[2], a[4])
    a[3], a[6] = m(a[3], a[6])
    a[5], a[8] = m(a[5], a[8])
    a[7], a[10] = m(a[7], a[10])
    a[9], a[11] = m(a[9], a[11])
    a[3], a[4] = m(a[3], a[4])
    a[5], a[6] = m(a[5], a[6])
    a[7], a[8] = m(a[7], a[8])
    a[9], a[10] = m(a[9], a[10])
    a[6], a[7] = m(a[6], a[7])
    return a

print('Defining function 15')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_15(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[1], a[2] = m(a[1], a[2])
    a[3], a[10] = m(a[3], a[10])
    a[4], a[14] = m(a[4], a[14])
    a[5], a[8] = m(a[5], a[8])
    a[6], a[13] = m(a[6], a[13])
    a[7], a[12] = m(a[7], a[12])
    a[9], a[11] = m(a[9], a[11])
    a[0], a[14] = m(a[0], a[14])
    a[1], a[5] = m(a[1], a[5])
    a[2], a[8] = m(a[2], a[8])
    a[3], a[7] = m(a[3], a[7])
    a[6], a[9] = m(a[6], a[9])
    a[10], a[12] = m(a[10], a[12])
    a[11], a[13] = m(a[11], a[13])
    a[0], a[7] = m(a[0], a[7])
    a[1], a[6] = m(a[1], a[6])
    a[2], a[9] = m(a[2], a[9])
    a[4], a[10] = m(a[4], a[10])
    a[5], a[11] = m(a[5], a[11])
    a[8], a[13] = m(a[8], a[13])
    a[12], a[14] = m(a[12], a[14])
    a[0], a[6] = m(a[0], a[6])
    a[2], a[4] = m(a[2], a[4])
    a[3], a[5] = m(a[3], a[5])
    a[7], a[11] = m(a[7], a[11])
    a[8], a[10] = m(a[8], a[10])
    a[9], a[12] = m(a[9], a[12])
    a[13], a[14] = m(a[13], a[14])
    a[0], a[3] = m(a[0], a[3])
    a[1], a[2] = m(a[1], a[2])
    a[4], a[7] = m(a[4], a[7])
    a[5], a[9] = m(a[5], a[9])
    a[6], a[8] = m(a[6], a[8])
    a[10], a[11] = m(a[10], a[11])
    a[12], a[13] = m(a[12], a[13])
    a[0], a[1] = m(a[0], a[1])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[6] = m(a[4], a[6])
    a[7], a[9] = m(a[7], a[9])
    a[10], a[12] = m(a[10], a[12])
    a[11], a[13] = m(a[11], a[13])
    a[1], a[2] = m(a[1], a[2])
    a[3], a[5] = m(a[3], a[5])
    a[8], a[10] = m(a[8], a[10])
    a[11], a[12] = m(a[11], a[12])
    a[3], a[4] = m(a[3], a[4])
    a[5], a[6] = m(a[5], a[6])
    a[7], a[8] = m(a[7], a[8])
    a[9], a[10] = m(a[9], a[10])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[5] = m(a[4], a[5])
    a[6], a[7] = m(a[6], a[7])
    a[8], a[9] = m(a[8], a[9])
    a[10], a[11] = m(a[10], a[11])
    a[5], a[6] = m(a[5], a[6])
    a[7], a[8] = m(a[7], a[8])
    return a

print('Defining function 16')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_16(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[13] = m(a[0], a[13])
    a[1], a[12] = m(a[1], a[12])
    a[2], a[15] = m(a[2], a[15])
    a[3], a[14] = m(a[3], a[14])
    a[4], a[8] = m(a[4], a[8])
    a[5], a[6] = m(a[5], a[6])
    a[7], a[11] = m(a[7], a[11])
    a[9], a[10] = m(a[9], a[10])
    a[0], a[5] = m(a[0], a[5])
    a[1], a[7] = m(a[1], a[7])
    a[2], a[9] = m(a[2], a[9])
    a[3], a[4] = m(a[3], a[4])
    a[6], a[13] = m(a[6], a[13])
    a[8], a[14] = m(a[8], a[14])
    a[10], a[15] = m(a[10], a[15])
    a[11], a[12] = m(a[11], a[12])
    a[0], a[1] = m(a[0], a[1])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[5] = m(a[4], a[5])
    a[6], a[8] = m(a[6], a[8])
    a[7], a[9] = m(a[7], a[9])
    a[10], a[11] = m(a[10], a[11])
    a[12], a[13] = m(a[12], a[13])
    a[14], a[15] = m(a[14], a[15])
    a[0], a[2] = m(a[0], a[2])
    a[1], a[3] = m(a[1], a[3])
    a[4], a[10] = m(a[4], a[10])
    a[5], a[11] = m(a[5], a[11])
    a[6], a[7] = m(a[6], a[7])
    a[8], a[9] = m(a[8], a[9])
    a[12], a[14] = m(a[12], a[14])
    a[13], a[15] = m(a[13], a[15])
    a[1], a[2] = m(a[1], a[2])
    a[3], a[12] = m(a[3], a[12])
    a[4], a[6] = m(a[4], a[6])
    a[5], a[7] = m(a[5], a[7])
    a[8], a[10] = m(a[8], a[10])
    a[9], a[11] = m(a[9], a[11])
    a[13], a[14] = m(a[13], a[14])
    a[1], a[4] = m(a[1], a[4])
    a[2], a[6] = m(a[2], a[6])
    a[5], a[8] = m(a[5], a[8])
    a[7], a[10] = m(a[7], a[10])
    a[9], a[13] = m(a[9], a[13])
    a[11], a[14] = m(a[11], a[14])
    a[2], a[4] = m(a[2], a[4])
    a[3], a[6] = m(a[3], a[6])
    a[9], a[12] = m(a[9], a[12])
    a[11], a[13] = m(a[11], a[13])
    a[3], a[5] = m(a[3], a[5])
    a[6], a[8] = m(a[6], a[8])
    a[7], a[9] = m(a[7], a[9])
    a[10], a[12] = m(a[10], a[12])
    a[3], a[4] = m(a[3], a[4])
    a[5], a[6] = m(a[5], a[6])
    a[7], a[8] = m(a[7], a[8])
    a[9], a[10] = m(a[9], a[10])
    a[11], a[12] = m(a[11], a[12])
    a[6], a[7] = m(a[6], a[7])
    a[8], a[9] = m(a[8], a[9])
    return a

print('Defining function 17')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_17(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[11] = m(a[0], a[11])
    a[1], a[15] = m(a[1], a[15])
    a[2], a[10] = m(a[2], a[10])
    a[3], a[5] = m(a[3], a[5])
    a[4], a[6] = m(a[4], a[6])
    a[8], a[12] = m(a[8], a[12])
    a[9], a[16] = m(a[9], a[16])
    a[13], a[14] = m(a[13], a[14])
    a[0], a[6] = m(a[0], a[6])
    a[1], a[13] = m(a[1], a[13])
    a[2], a[8] = m(a[2], a[8])
    a[4], a[14] = m(a[4], a[14])
    a[5], a[15] = m(a[5], a[15])
    a[7], a[11] = m(a[7], a[11])
    a[0], a[8] = m(a[0], a[8])
    a[3], a[7] = m(a[3], a[7])
    a[4], a[9] = m(a[4], a[9])
    a[6], a[16] = m(a[6], a[16])
    a[10], a[11] = m(a[10], a[11])
    a[12], a[14] = m(a[12], a[14])
    a[0], a[2] = m(a[0], a[2])
    a[1], a[4] = m(a[1], a[4])
    a[5], a[6] = m(a[5], a[6])
    a[7], a[13] = m(a[7], a[13])
    a[8], a[9] = m(a[8], a[9])
    a[10], a[12] = m(a[10], a[12])
    a[11], a[14] = m(a[11], a[14])
    a[15], a[16] = m(a[15], a[16])
    a[0], a[3] = m(a[0], a[3])
    a[2], a[5] = m(a[2], a[5])
    a[6], a[11] = m(a[6], a[11])
    a[7], a[10] = m(a[7], a[10])
    a[9], a[13] = m(a[9], a[13])
    a[12], a[15] = m(a[12], a[15])
    a[14], a[16] = m(a[14], a[16])
    a[0], a[1] = m(a[0], a[1])
    a[3], a[4] = m(a[3], a[4])
    a[5], a[10] = m(a[5], a[10])
    a[6], a[9] = m(a[6], a[9])
    a[7], a[8] = m(a[7], a[8])
    a[11], a[15] = m(a[11], a[15])
    a[13], a[14] = m(a[13], a[14])
    a[1], a[2] = m(a[1], a[2])
    a[3], a[7] = m(a[3], a[7])
    a[4], a[8] = m(a[4], a[8])
    a[6], a[12] = m(a[6], a[12])
    a[11], a[13] = m(a[11], a[13])
    a[14], a[15] = m(a[14], a[15])
    a[1], a[3] = m(a[1], a[3])
    a[2], a[7] = m(a[2], a[7])
    a[4], a[5] = m(a[4], a[5])
    a[9], a[11] = m(a[9], a[11])
    a[10], a[12] = m(a[10], a[12])
    a[13], a[14] = m(a[13], a[14])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[6] = m(a[4], a[6])
    a[5], a[7] = m(a[5], a[7])
    a[8], a[10] = m(a[8], a[10])
    a[3], a[4] = m(a[3], a[4])
    a[6], a[8] = m(a[6], a[8])
    a[7], a[9] = m(a[7], a[9])
    a[10], a[12] = m(a[10], a[12])
    a[5], a[6] = m(a[5], a[6])
    a[7], a[8] = m(a[7], a[8])
    a[9], a[10] = m(a[9], a[10])
    a[11], a[12] = m(a[11], a[12])
    a[4], a[5] = m(a[4], a[5])
    a[6], a[7] = m(a[6], a[7])
    a[8], a[9] = m(a[8], a[9])
    a[10], a[11] = m(a[10], a[11])
    a[12], a[13] = m(a[12], a[13])
    return a

print('Defining function 18')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_18(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[1] = m(a[0], a[1])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[5] = m(a[4], a[5])
    a[6], a[7] = m(a[6], a[7])
    a[8], a[9] = m(a[8], a[9])
    a[10], a[11] = m(a[10], a[11])
    a[12], a[13] = m(a[12], a[13])
    a[14], a[15] = m(a[14], a[15])
    a[16], a[17] = m(a[16], a[17])
    a[0], a[2] = m(a[0], a[2])
    a[1], a[3] = m(a[1], a[3])
    a[4], a[12] = m(a[4], a[12])
    a[5], a[13] = m(a[5], a[13])
    a[6], a[8] = m(a[6], a[8])
    a[9], a[11] = m(a[9], a[11])
    a[14], a[16] = m(a[14], a[16])
    a[15], a[17] = m(a[15], a[17])
    a[0], a[14] = m(a[0], a[14])
    a[1], a[16] = m(a[1], a[16])
    a[2], a[15] = m(a[2], a[15])
    a[3], a[17] = m(a[3], a[17])
    a[0], a[6] = m(a[0], a[6])
    a[1], a[10] = m(a[1], a[10])
    a[2], a[9] = m(a[2], a[9])
    a[7], a[16] = m(a[7], a[16])
    a[8], a[15] = m(a[8], a[15])
    a[11], a[17] = m(a[11], a[17])
    a[1], a[4] = m(a[1], a[4])
    a[3], a[9] = m(a[3], a[9])
    a[5], a[7] = m(a[5], a[7])
    a[8], a[14] = m(a[8], a[14])
    a[10], a[12] = m(a[10], a[12])
    a[13], a[16] = m(a[13], a[16])
    a[0], a[1] = m(a[0], a[1])
    a[2], a[5] = m(a[2], a[5])
    a[3], a[13] = m(a[3], a[13])
    a[4], a[14] = m(a[4], a[14])
    a[7], a[9] = m(a[7], a[9])
    a[8], a[10] = m(a[8], a[10])
    a[12], a[15] = m(a[12], a[15])
    a[16], a[17] = m(a[16], a[17])
    a[1], a[2] = m(a[1], a[2])
    a[3], a[5] = m(a[3], a[5])
    a[4], a[6] = m(a[4], a[6])
    a[11], a[13] = m(a[11], a[13])
    a[12], a[14] = m(a[12], a[14])
    a[15], a[16] = m(a[15], a[16])
    a[4], a[8] = m(a[4], a[8])
    a[5], a[12] = m(a[5], a[12])
    a[6], a[10] = m(a[6], a[10])
    a[7], a[11] = m(a[7], a[11])
    a[9], a[13] = m(a[9], a[13])
    a[1], a[4] = m(a[1], a[4])
    a[2], a[8] = m(a[2], a[8])
    a[3], a[6] = m(a[3], a[6])
    a[5], a[7] = m(a[5], a[7])
    a[9], a[15] = m(a[9], a[15])
    a[10], a[12] = m(a[10], a[12])
    a[11], a[14] = m(a[11], a[14])
    a[13], a[16] = m(a[13], a[16])
    a[2], a[4] = m(a[2], a[4])
    a[5], a[8] = m(a[5], a[8])
    a[6], a[10] = m(a[6], a[10])
    a[7], a[11] = m(a[7], a[11])
    a[9], a[12] = m(a[9], a[12])
    a[13], a[15] = m(a[13], a[15])
    a[3], a[5] = m(a[3], a[5])
    a[6], a[8] = m(a[6], a[8])
    a[7], a[10] = m(a[7], a[10])
    a[9], a[11] = m(a[9], a[11])
    a[12], a[14] = m(a[12], a[14])
    a[3], a[4] = m(a[3], a[4])
    a[5], a[6] = m(a[5], a[6])
    a[7], a[8] = m(a[7], a[8])
    a[9], a[10] = m(a[9], a[10])
    a[11], a[12] = m(a[11], a[12])
    a[13], a[14] = m(a[13], a[14])
    return a

print('Defining function 19')
@nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
def sort_small_array_19(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
    a[0], a[12] = m(a[0], a[12])
    a[1], a[4] = m(a[1], a[4])
    a[2], a[8] = m(a[2], a[8])
    a[3], a[5] = m(a[3], a[5])
    a[6], a[17] = m(a[6], a[17])
    a[7], a[11] = m(a[7], a[11])
    a[9], a[14] = m(a[9], a[14])
    a[10], a[13] = m(a[10], a[13])
    a[15], a[16] = m(a[15], a[16])
    a[0], a[2] = m(a[0], a[2])
    a[1], a[7] = m(a[1], a[7])
    a[3], a[6] = m(a[3], a[6])
    a[4], a[11] = m(a[4], a[11])
    a[5], a[17] = m(a[5], a[17])
    a[8], a[12] = m(a[8], a[12])
    a[10], a[15] = m(a[10], a[15])
    a[13], a[16] = m(a[13], a[16])
    a[14], a[18] = m(a[14], a[18])
    a[3], a[10] = m(a[3], a[10])
    a[4], a[14] = m(a[4], a[14])
    a[5], a[15] = m(a[5], a[15])
    a[6], a[13] = m(a[6], a[13])
    a[7], a[9] = m(a[7], a[9])
    a[11], a[17] = m(a[11], a[17])
    a[16], a[18] = m(a[16], a[18])
    a[0], a[7] = m(a[0], a[7])
    a[1], a[10] = m(a[1], a[10])
    a[4], a[6] = m(a[4], a[6])
    a[9], a[15] = m(a[9], a[15])
    a[11], a[16] = m(a[11], a[16])
    a[12], a[17] = m(a[12], a[17])
    a[13], a[14] = m(a[13], a[14])
    a[0], a[3] = m(a[0], a[3])
    a[2], a[6] = m(a[2], a[6])
    a[5], a[7] = m(a[5], a[7])
    a[8], a[11] = m(a[8], a[11])
    a[12], a[16] = m(a[12], a[16])
    a[1], a[8] = m(a[1], a[8])
    a[2], a[9] = m(a[2], a[9])
    a[3], a[4] = m(a[3], a[4])
    a[6], a[15] = m(a[6], a[15])
    a[7], a[13] = m(a[7], a[13])
    a[10], a[11] = m(a[10], a[11])
    a[12], a[18] = m(a[12], a[18])
    a[1], a[3] = m(a[1], a[3])
    a[2], a[5] = m(a[2], a[5])
    a[6], a[9] = m(a[6], a[9])
    a[7], a[12] = m(a[7], a[12])
    a[8], a[10] = m(a[8], a[10])
    a[11], a[14] = m(a[11], a[14])
    a[17], a[18] = m(a[17], a[18])
    a[0], a[1] = m(a[0], a[1])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[8] = m(a[4], a[8])
    a[6], a[10] = m(a[6], a[10])
    a[9], a[12] = m(a[9], a[12])
    a[14], a[15] = m(a[14], a[15])
    a[16], a[17] = m(a[16], a[17])
    a[1], a[2] = m(a[1], a[2])
    a[5], a[8] = m(a[5], a[8])
    a[6], a[7] = m(a[6], a[7])
    a[9], a[11] = m(a[9], a[11])
    a[10], a[13] = m(a[10], a[13])
    a[14], a[16] = m(a[14], a[16])
    a[15], a[17] = m(a[15], a[17])
    a[3], a[6] = m(a[3], a[6])
    a[4], a[5] = m(a[4], a[5])
    a[7], a[9] = m(a[7], a[9])
    a[8], a[10] = m(a[8], a[10])
    a[11], a[12] = m(a[11], a[12])
    a[13], a[14] = m(a[13], a[14])
    a[15], a[16] = m(a[15], a[16])
    a[3], a[4] = m(a[3], a[4])
    a[5], a[6] = m(a[5], a[6])
    a[7], a[8] = m(a[7], a[8])
    a[9], a[10] = m(a[9], a[10])
    a[11], a[13] = m(a[11], a[13])
    a[12], a[14] = m(a[12], a[14])
    a[2], a[3] = m(a[2], a[3])
    a[4], a[5] = m(a[4], a[5])
    a[6], a[7] = m(a[6], a[7])
    a[8], a[9] = m(a[8], a[9])
    a[10], a[11] = m(a[10], a[11])
    a[12], a[13] = m(a[12], a[13])
    a[14], a[15] = m(a[14], a[15])
    return a
    
dummy=np.arange(63).astype(np.uint64)
print('Compiling functions (numba)...')
print('..compiling 1 of 63, '); sort_small_array_1(dummy[:1])
print('..compiling 2 of 63, '); sort_small_array_2(dummy[:2])
print('..compiling 3 of 63, '); sort_small_array_3(dummy[:3])
print('..compiling 4 of 63, '); sort_small_array_4(dummy[:4])
print('..compiling 5 of 63, '); sort_small_array_5(dummy[:5])
print('..compiling 6 of 63, '); sort_small_array_6(dummy[:6])
print('..compiling 7 of 63, '); sort_small_array_7(dummy[:7])
print('..compiling 8 of 63, '); sort_small_array_8(dummy[:8])
print('..compiling 9 of 63, '); sort_small_array_9(dummy[:9])
print('..compiling 10 of 63, '); sort_small_array_10(dummy[:10])

推荐答案

编译时间分析

乍一看,时代并不是以指数形式增长,而是以二次曲线形式增长.我们可以通过绘制编译时间与函数号的关系图来看到这一点.

timing plot

事情是the number of line also grows significantly and is highly correlated with the time taken to compile the function.在100中,排序网络的大小增长,因此编译时间应该至少增长与此相同.

事实上,有些编译步骤并不是与输入代码大小成线性关系,而是比这更大.一些步骤,如优化,可以在O(n²)中增长.例如,register allocation是一个特别昂贵的步骤,特别是在你的情况下.事实上,众所周知,尽管编译器在实践中使用相对较快的启发式算法,但如果我们想要找到最佳解决方案,TOP是NP-Hard.有关编译器算法复杂性的更多信息,请阅读this post.在您的情况下,我预计大多数操作要么在O(n)次完成,要么在O(n log n)次.这意味着函数号v的编译时间为O(v log(v)**3).结果表明,当前结果与O(n log(n))次编译时间非常匹配,其中n是行数,证实了上面提到的预期的编译时间复杂性.

最重要的是,Numba并没有被设计为特别快地生成代码,因为Numba代码预计会很小(与本机代码甚至Cython代码相反).AFAIK,负责将Python代码转换为LLVM中间表示的代码的很大一部分是用Python语言完成的(因此它被解释,并且相当慢).


更快的编译速度第1部分:内联

这就是说,一个问题是您使用100,它告诉Numba手动内联函数本身.这会显著增加生成的IR代码的大小,从而缩短编译时间.请注意,如果LLVM认为内联是值得的,那么它可以在没有编译标志的情况下进行内联.This manual inlining process takes most of the compilation time在我的机器上.实际上,以下是使用和不使用它时的执行时间:

timings with/without manual inlining

最后一次(n°17)的时间从3010ms减少到1360ms.


更快的编译速度第2部分:减少重复代码

还有另一个问题:当你做一个天真的a[1],Numba generates a code to access data in the Numpy array.问题是,Numba需要考虑Numpy的回绕特性,即不能保证为1的跨度,并在此基础上提取Numy数组的值.这为这种基本的基本操作生成了一个重要的代码,在您的代码中重复了大约2000次.问题是Numba不支持基本的C数组,所以我不认为我们可以在Numba中完全消除这一开销(Cython可以使用用户标志来禁用Numpy/CPython特性,如Wraparound).

尽管如此,我们可以avoid Numba to generate a lot of repeated code并将负担转移到更优化的LLVM.一种解决方案是修改函数m,使得它基于索引执行数组读/写.这大大减少了复制代码的大小.下面是修改后的部分代码:

import numba as nb
import numpy as np

# This function calculates the min and the max of his parameters.
@nb.njit((nb.uint64[:], nb.uint64, nb.uint64),fastmath=True)
def m(arr: 'np.ndarray[np.uint64]', ia: np.uint64, ib: np.uint64):
    va = arr[ia]
    vb = arr[ib]
    arr[ia] = min(va, vb)
    arr[ib] = max(va, vb)

def run1(): 
    @nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
    def sort_small_array_1(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
        return a

def run2(): 
    print('Defining function 2')
    @nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
    def sort_small_array_2(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
        m(a, 0, 1)
        return a

def run3():
    print('Defining function 3')
    @nb.njit(nb.uint64[:](nb.uint64[:]),fastmath=True)
    def sort_small_array_3(a: 'np.ndarray[np.uint64]') -> 'np.ndarray[np.uint64]':
        m(a, 0, 2)
        m(a, 0, 1)
        m(a, 1, 2)
        return a

# [...]

以下是产生的时间安排:

plot of timing with all compilation optimizations

除了最快的功能外,几乎所有功能的计时都在10 times faster compilation左右(例如,3010毫秒与最后一个功能的295毫秒).

需要判断结果代码的性能,因为LLVM可能会生成次优代码.请注意,ahead-of-time compilation更适合于这样的用例,因为编译只完成一次.事实上,是native languages like C are perfect for this use-case.代码的编译速度应该快得多,生成的代码也会更快,因为没有环绕式.最重要的是,可以并行编译多个C文件,这在Numba中是不可能的.


注意到

顺便说一下,large sorting networks are generally inefficient号.首先,它们的大小对于大型内存来说是次优的(它们的增长速度是O(n log² n),而快速排序算法运行的速度是O(n log n).此外,CPU并不是为执行大型代码而设计的.由于现代主流CPU中有许多小缓存(微操作缓存、循环流检测器、一级指令缓存等),因此大型代码的执行效率较低.我建议您重新考虑是否需要使用大于15的排序网络,特别是对于Numba代码.正因为如此,对于几十种商品,optimized insertion sort可以比大型分拣网络更快.

请注意,代码的"编译函数"部分是无用的,因为当提供签名时,Numba函数是eagerly compiled(这是您代码中的情况).


结论

经验法则是"Don't repeat yourself" (DRY)!这显然对人类、编译器和CPU都没有好处.

Python-3.x相关问答推荐

需要使用regex匹配字符串的帮助,直到最后一次出现开闭括号,开闭括号中的值是可选的

具有多个值的极轴旋转和熔化/取消旋转(反转旋转)操作(Pandas 堆叠/取消堆叠交替/UDF覆盖)

Python避免捕获特定异常

Python多处理池:缺少一个进程

根据第一个字典的值序列对第二个字典进行排序

将列表转换为 pandas 数据框,其中列表包含字典

估计列表中连续对的数量

通过匹配第一列的行值,逐个单元格地添加两个Pandas 数据框中的浮点数

如何将列表和字典逐行组合在一起

在 jupyter notebook 的单元格中使用 sudo

合并两个numpy数组

为什么Pandas会在 NaN 上合并?

如何在 Python 3 中通过 IP 获取 WhoIs 信息?

在 Pandas 数据框中显示对图

plt.cm.get_cmap 中可以使用哪些名称?

TypeError:多个基地有实例布局冲突

如何在python中创建代码对象?

Python 2 与 Python 3 - urllib 格式

哪个更有效:Python 文档字符串还是类型提示?

注册 Celery 基于类的任务