You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 3.X:为何numexpr.evaluate()性能不如eval()?

Why is numexpr.evaluate() slower than numpy/eval() in this test?

Great question! Let's break down why you're seeing numexpr underperform compared to eval() here, even though it's built to speed up numerical computations:

1. Small Dataset Size is the Biggest Culprit

numexpr's strengths shine when working with large arrays (think hundreds of thousands to millions of elements). It incurs unavoidable overhead from:

  • Compiling your expression into optimized machine code
  • Spawning and managing threads for parallel execution

With only 1000 elements in your x array, this overhead completely cancels out any performance gains from numexpr's optimizations. In contrast, eval() directly calls numpy's highly tuned vectorized operations—these are already blazingly fast for small datasets, with almost no startup cost.

2. Complex Number Overhead

Your expression involves complex arithmetic, which numexpr supports, but numpy has decades of optimized low-level implementations for complex operations. For small datasets, numpy's native vectorized complex calculations will often outpace numexpr's generalized approach, which adds a layer of abstraction that isn't worth it for tiny workloads.

3. Threading Overhead (Even When Disabled)

Even if you uncomment ne.set_num_threads(8), using multiple threads for a tiny array introduces unnecessary overhead. Thread management, data partitioning, and inter-thread communication all take time that's not justified when the computation itself is trivial.


Let's Test with a Larger Dataset

If you scale up x to, say, 1,000,000 elements, you'll likely see numexpr pull ahead. Here's a modified snippet to try:

import datetime
import numpy as np
import numexpr as ne

expr = '11808000.0*1j*x**2*exp(2.5e-10*1j*x) + 1512000.0*1j*x**2*exp(5.0e-10*1j*x)'

# Larger dataset
x_large = np.array([m+3j for m in range(1, 1_000_001)])

# eval test
start_eval = datetime.datetime.now()
namespace = dict(x=x_large, exp=np.exp)
result_eval = eval(expr, namespace)
end_eval = datetime.datetime.now()
print("time by using eval : %s" % (end_eval- start_eval))

# numexpr test with optimal threads
ne.set_num_threads(ne.detect_number_of_cores())
start_ne = datetime.datetime.now()
result_ne = ne.evaluate(expr, local_dict={'x': x_large})
end_ne = datetime.datetime.now()
print("time by using numexpr: %s" % (end_ne- start_ne))

Additional Tips

  • Always use ne.detect_number_of_cores() to set thread count dynamically instead of hardcoding—it matches your CPU's actual capabilities.
  • For very small arrays, stick with numpy's native operations—numexpr isn't designed for this use case.
  • If you're working with complex expressions regularly, consider pre-compiling them with ne.compile() to reduce startup overhead for repeated runs.

Your original test code for reference:

import datetime
import numpy as np
import numexpr as ne

expr = '11808000.0*1j*x**2*exp(2.5e-10*1j*x) + 1512000.0*1j*x**2*exp(5.0e-10*1j*x)'

# use eval
start_eval = datetime.datetime.now()
namespace = dict(x=np.array([m+3j for m in range(1, 1001)]), exp=np.exp)
result_eval = eval(expr, namespace)
end_eval = datetime.datetime.now()
# print(result)
print("time by using eval : %s" % (end_eval- start_eval))

# use numexpr
# ne.set_num_threads(8)
start_ne = datetime.datetime.now()
x = np.array([n+3j for n in range(1, 1001)])
result_ne = ne.evaluate(expr)
end_ne = datetime.datetime.now()
# print(result_ne)
print("time by using numexpr: %s" % (end_ne- start_ne))

Original run results:

time by using eval : 0:00:00.002998
time by using numexpr: 0:00:00.052969

内容的提问来源于stack exchange,提问作者sun0727

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:52:25