在代码中,您正在访问和修改NumPy中的单个元素
array (l[j] = False)
.NumPy数组针对整个数组或切片的操作进行了优化,而不是针对单个元素。
NumPy数组由固定大小的连续内存支持。对于涉及许多随机访问模式的小规模操作,访问这些内存位置的额外开销可能会使它们比Python列表慢,Python列表是指向对象的指针。
为了利用NumPy的优势,您应该致力于消除循环并使用矢量化操作。这是一个优化版本:
import numpy as np
def PrimeTableOptimized(n: int) -> list[int]:
if n < 2:
return []
if n == 2:
return [2]
sieve = np.ones(n//2, dtype=bool) # Only consider odd numbers
sieve[0] = False # 1 is not prime
for i in range(1, int(n**0.5) // 2 + 1):
if sieve[i]:
start = 2*i*(i + 1)
sieve[start::2*i+1] = False
primes = [2] + (2*np.nonzero(sieve)[0] + 1).tolist()
return primes
sieve[start::2*i+1] = False
利用NumPy的切片功能,在单个操作中直接标记所有非素数索引。
通过仅存储奇数
sieve
,我们减小了数组的大小,这提高了内存局部性并加快了操作速度。
使用
np.nonzero(sieve)
检索筛选器所在的索引
True
,以及矢量化算法
2*indices+1
生成素数。
由于Python循环的开销减少,这个优化版本应该更接近或更快地实现基于列表的实现;使用NumPy的高效切片和矢量化操作。