我正在编写一个帮助类来计算网格上的参数化函数.由于网格不会随参数而改变,所以我 Select 将其创建为一个class属性.
然而,我意识到,与将网格作为全局变量相比,将其作为class属性会导致显著的性能下降.更有趣的是,2D网格的性能差异似乎在1D网格中消失了.
以下是一个最低限度的"工作"例子,说明了这个问题:
import numpy as np
import time
grid_1d_size = 25000000
grid_2d_size = 5000
x_min, x_max = 0, np.pi / 2
y_min, y_max = -np.pi / 4, np.pi / 4
# Grid evaluation (2D) with grid as class attribute
class GridEvaluation2DWithAttribute:
def __init__(self):
self.x_2d_values = np.linspace(x_min, x_max, grid_2d_size, dtype=np.float128)
self.y_2d_values = np.linspace(y_min, y_max, grid_2d_size, dtype=np.float128)
def grid_evaluate(self):
cost_values = np.cos(self.x_2d_values[:, None] * self.y_2d_values[None, :])
return cost_values
grid_eval_2d_attribute = GridEvaluation2DWithAttribute()
initial_time = time.process_time()
grid_eval_2d_attribute.grid_evaluate()
final_time = time.process_time()
print(f"2d grid, with grid as class attribute: {final_time - initial_time} seconds")
# Grid evaluation (1D) with grid as global variable
x_2d_values = np.linspace(x_min, x_max, grid_2d_size)
y_2d_values = np.linspace(y_min, y_max, grid_2d_size)
class GridEvaluation2DWithGlobal:
def __init__(self):
pass
def grid_evaluate(self):
cost_values = np.cos(x_2d_values[:, None] * y_2d_values[None, :])
return cost_values
grid_eval_2d_global = GridEvaluation2DWithGlobal()
initial_time = time.process_time()
grid_eval_2d_global.grid_evaluate()
final_time = time.process_time()
print(f"2d grid, with grid as global variable: {final_time - initial_time} seconds")
# Grid evaluation (1D) with grid as class attribute
class GridEvaluation1DWithAttribute:
def __init__(self):
self.x_1d_values = np.linspace(x_min, x_max, grid_1d_size, dtype=np.float128)
def grid_evaluate(self):
cost_values = np.cos(self.x_1d_values)
return cost_values
grid_eval_1d_attribute = GridEvaluation1DWithAttribute()
initial_time = time.process_time()
grid_eval_1d_attribute.grid_evaluate()
final_time = time.process_time()
print(f"1d grid, with grid as class attribute: {final_time - initial_time} seconds")
# Grid evaluation (1D) with grid as global variable
x_1d_values = np.linspace(x_min, x_max, grid_1d_size, dtype=np.float128)
class GridEvaluation1DWithGlobal:
def __init__(self):
pass
def grid_evaluate(self):
cost_values = np.cos(x_1d_values)
return cost_values
grid_eval_1d_global = GridEvaluation1DWithGlobal()
initial_time = time.process_time()
grid_eval_1d_global.grid_evaluate()
final_time = time.process_time()
print(f"1d grid, with grid as global variable: {final_time - initial_time} seconds")
这是我得到的输出:
2d grid, with grid as class attribute: 0.8012442529999999 seconds
2d grid, with grid as global variable: 0.20206781899999982 seconds
1d grid, with grid as class attribute: 2.0631387639999996 seconds
1d grid, with grid as global variable: 2.136266148 seconds
如何解释这种性能差异?
我将网格从class属性移动到全局变量.我认为这一变化对性能是中性的.然而,业绩出现了重大变化.