Nova 语言解释器性能优化开发日志
1. Nova 语言的性能短板
在对 Nova 语言解释器进行性能测试时,发现其存在明显的性能短板 以测试示例二为例,每秒仅能运行 30125 次 经过深入分析,发现问题主要集中在以下几个方面:
- 表达式解析和求值过程中存在大量重复计算,增加了不必要的开销
-
- 逻辑结构复杂,处理逻辑运算符和比较运算符时,多次嵌套函数调用,降低了执行效率
-
- 频繁的字符串操作,如拼接和分割,在 Python 中相对耗时,影响了整体性能
2. 优化角度
- 针对上述性能问题,从缓存机制、逻辑结构和字符串操作三个角度进行优化:
-
- 缓存机制强化:将
functools.lru_cache的缓存大小从 256 提升至 1024,同时新增self.block_cache用于缓存代码块的解释结果,避免重复解析相同代码
- 缓存机制强化:将
-
- 逻辑结构优化:减少逻辑和比较运算符处理时的不必要函数调用,简化逻辑分支,避免重复计算。 同时减少正则表达式的使用,采用更直接的字符串分割方法
- 减少字符串操作:尽量使用列表或其他数据结构替代字符串拼接和分割操作,减少性能损耗
3. 优化前后运行逻辑对比
修改前运行逻辑
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
A([开始]):::startend --> B(读取代码):::process
B --> C(移除代码中的注释):::process
C --> D(按行分割代码内容):::process
D --> E{是否还有行未处理?}:::decision
E -- 是 --> F(处理当前行代码):::process
F --> G{判断语句类型}:::decision
G -- 打印语句 --> H(提取表达式并求值打印):::process
G -- 输入语句 --> I(提取变量和表达式求值赋值):::process
G -- 常量赋值 --> J(提取常量和值并求值赋值):::process
G -- 条件语句 --> K(读取条件代码块递归解释):::process
G -- 变量赋值 --> L(提取变量和表达式求值赋值):::process
G -- 其他 --> M(输出未知语句类型提示):::process
H --> N(继续处理下一行):::process
I --> N
J --> N
K --> N
L --> N
M --> N
N --> E
E -- 否 --> O([结束]):::startend
修改后运行逻辑
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
A([开始]):::startend --> B(读取代码):::process
B --> C{代码是否缓存?}:::decision
C -- 是 --> D(使用缓存结果):::process
C -- 否 --> E(移除注释):::process
E --> F(按行分割代码):::process
F --> G{是否还有行未处理?}:::decision
G -- 是 --> H(处理当前行):::process
H --> I{语句类型判断}:::decision
I -- 打印语句 --> J(提取表达式并检查缓存求值打印):::process
I -- 输入语句 --> K(提取变量和表达式并检查缓存求值赋值):::process
I -- 常量赋值 --> L(提取常量和值并检查缓存求值赋值):::process
I -- 条件语句 --> M(读取条件代码块并检查缓存递归解释):::process
I -- 变量赋值 --> N(提取变量和表达式并检查缓存求值赋值):::process
I -- 其他 --> O(输出未知语句类型):::process
J --> P(继续下一行):::process
K --> P
L --> P
M --> P
N --> P
O --> P
P --> G
G -- 否 --> Q(缓存解释结果):::process
D --> R([结束]):::startend
Q --> R
4. 优化后的性能
优化后,Nova 语言解释器的性能得到显著提升,测试示例二的高峰值达到每秒 301871 次,平均值为每秒 201375 次,以下是具体数据对比:
| 阶段 | 每秒执行次数 |
|---|---|
| 优化前 | 30125 |
| 优化后(高峰值) | 301871 |
| 优化后(平均值) | 201375 |
此次优化大幅提高了 Nova 语言解释器的执行效率,后续将持续关注性能表现,进一步探索优化空间
测试示例2(Nova语言编写):
a = 1-2 + 3 * 4 % 5 // 2 ** 3
cond1 = 10 > 5
cond2 = 20 < 30
cond3 = 4 == 4
cond4 = 5 != 6
cond5 = cond3 xor cond4
cond6 = not cond5
cond7 = cond1 and cond2
final_cond = cond7 or cond6
if final_cond:
nop