给流水线换上高速机器,不等于整条线都会变快:如果每处理一个零件,都要停下来检查、交接,时间仍会耗在门口。Numba也是如此。它会在程序运行时,把数值型Python代码编译成机器码;但每次从Python进入编译函数,都可能付出参数检查、对象转换和调度成本。把计算拆成许多微小调用,省下的计算时间就可能被这些固定开销吃掉。
Matthew Mayo在KDnuggets的示例中,让程序对一千万个数组元素做循环计算。普通Python循环最佳用时3.0789秒;使用Numba的@njit后,稳定运行的最佳用时为0.0384秒,作者测得约80.2倍加速。不过,首次调用还花了0.2799秒完成JIT——即时编译,也就是运行到函数时才生成机器码。只测第一次,容易把编译等待误算进日常速度。
更值得先检查的因此不是编译参数,而是边界画在哪里:让Numba覆盖整段反复执行、最耗时间的“热路径”,一次交给它足够多的工作,并避免在循环里频繁往返Python与编译代码。上述数字来自作者在Numba 0.67.0下的测试,不能直接外推到所有程序。