# 2025/12/27 工作日志

本次更新修复了一些致命漏洞，解决了一些内存泄漏问题，重新设计了移植接口架构，并添加了``stdc++``的实现。
本次更新发行``2.4.58``版本。

### 修复了运算中产生的错误

在运算过程中，出现了如下致命漏洞：

* 若将字符串、数列、类转为布尔值，程序会崩溃
* 若将类或空值进行判等运算，程序会崩溃

这些漏洞来自``TypeCalculator.cpp``，目前已被修复。

### 重新设计移植接口架构

为了增强项目的可移植性，我将移植接口做了模块化设计。接下来，我会逐步将项目主体代码也进行模块化，从而实现每个项目主体模块依赖必要的移植接口模块。开发者在移植时可以根据功能需求，删减掉不需要的项目主体模块，从而了解需要移植哪些移植接口模块，最后自选或动手开发移植接口模块。

具体的移植接口模块设计方案和原理，被记录到了``移植接口开发指导.md``中。

除部分函数外，大部分移植接口的接口约束代码被迁移到了``stamon::interface``命名空间中。

### 对部分项目主体代码进行内存优化

我使用``move``和左右值引用减少了无用复制，从而减少了内存分配次数。具体修改的项目主体文件为：

* ``Main.cpp``
* ``Stamon.cpp``
* ``AstIr.cpp``
* ``SFN.cpp``
* ``AstIrReader.cpp``

接下来我可能会重构代码以进行更完全的优化。

### 微调了基于stdc的移植接口实现

##### 更新了HashMap和String

我使用``move``和左右值引用减少了无用复制，从而减少了内存分配次数。

对于``HashMap``，我还额外添加了``getValList()``方法。

##### 调整了EasySmartPtr的实现

以往的``EasySmartPtr``只能对单个对象进行内存管理，若管理数组则会发生内存泄漏。

因此，我参考了``stdc++``的智能指针设置。现在，我们可以使用``EasySmartPtr<T[]>``来表示一个数组指针。智能指针会智能识别类型并作出相应的内存释放方式，从而解决内存泄漏问题。

在特定情况下，智能指针不能删除其所托管的内存。因此各个代码都编写了“什么都不销毁”的内存销毁函数。为了减少冗余代码，我在``StamonLib.hpp``中统一定义了``DestoyNothing()``函数，他的实现如下：

```C++
// 一个什么也不做的销毁函数，用于智能指针
template<typename T> void DestroyNothing(T *p) {
	return;
}
```

由于``EasySmartPtr``的定义被调整，而跟着被调整的项目主体文件如下：

* ``BufferStream.cpp``
* ``AstRunner.cpp``


##### 调整了Stack的模板类型

以往的``Stack``必须以指针为元素类型，这使得内存管理尤为困难。

因此，我重新调整了``Stack``的实现。现在``Stack``的元素类型可以是指针以外的其他类型了。

以往，``Stack<T>``托管的元素类型是``T*``；现在，``Stack<T>``托管的元素类型是``T``。

由于``Stack``的模板类型定义被调整，而跟着被调整的项目主体文件如下：

* ``AstFileReader.cpp``
* ``AstFileWriter.cpp``
* ``AstIr.cpp``

### 添加了基于stdc++的移植接口实现及性能分析

我使用``stdc++``实现了移植接口，支持``stdc++``的平台可以选用该实现，通常情况下，``stdc++``实现的性能更优。

为了更直观、客观的看到基于``stdc``的实现和基于``stdc++``的实现的差距，以及本次更新的优化效果，我选取了``2.4.53``内部版本与``2.4.58``发行版进行对比，两个版本都使用Makefile编译。测试在``WSL``（版本: ``2.6.3.0``，内核版本: ``6.6.87.2-1``）中的``Alpine Linux v3.23 x86_64``运行，我采用``perf 6.18.6``作为性能测试工具。

我们测试了三个样例：十万次空循环、朴素递归计算斐波那契数列第三十项、从2到50000的埃氏素数筛。

##### 十万次空循环的性能测试

测试代码如下：

```
import std;

def i=1;
while i<=100000: i+=1;

println("done!");
```

生成的原始结果分别如下：

```
# 优化前
 Performance counter stats for './stamon_2.4.53 run loop_2.4.53.stvc':

         198894300      task-clock                       #    0.960 CPUs utilized
                21      context-switches                 #  105.584 /sec
                 0      cpu-migrations                   #    0.000 /sec
              3651      page-faults                      #   18.356 K/sec
        1768127633      instructions                     #    2.35  insn per cycle
         752404789      cycles                           #    3.783 GHz
         371318980      branches                         #    1.867 G/sec
           2888284      branch-misses                    #    0.78% of all branches

       0.207134601 seconds time elapsed

       0.187452000 seconds user
       0.012225000 seconds sys
```

```
# 优化后
 Performance counter stats for './stamon_2.4.58 run loop_2.4.58.stvc':

         140413600      task-clock                       #    0.916 CPUs utilized
                38      context-switches                 #  270.629 /sec
                 0      cpu-migrations                   #    0.000 /sec
              3850      page-faults                      #   27.419 K/sec
        1053122765      instructions                     #    2.00  insn per cycle
         525891656      cycles                           #    3.745 GHz
         221371017      branches                         #    1.577 G/sec
           1007838      branch-misses                    #    0.46% of all branches

       0.153222000 seconds time elapsed

       0.125370000 seconds user
       0.016176000 seconds sys
```

##### 朴素递归计算斐波那契数列第三十项的性能测试

测试代码如下：

```
import std;

func fib(x) {
    if x<=2: return 1;
    return fib(x-1)+fib(x-2);
}

println(fib(30));
```

生成的原始结果分别如下：

```
# 优化前
832040

 Performance counter stats for './stamon_2.4.53 run fib_2.4.53.stvc':

        5865342000      task-clock                       #    0.998 CPUs utilized
                28      context-switches                 #    4.774 /sec
                 1      cpu-migrations                   #    0.170 /sec
             27891      page-faults                      #    4.755 K/sec
       47337946707      instructions                     #    2.16  insn per cycle
       21879201815      cycles                           #    3.730 GHz
        9934221064      branches                         #    1.694 G/sec
         106778379      branch-misses                    #    1.07% of all branches

       5.876182195 seconds time elapsed

       5.794224000 seconds user
       0.071878000 seconds sys
```

```
# 优化后
 Performance counter stats for './stamon_2.4.58 run fib_2.4.58.stvc':

        4374857300      task-clock                       #    0.996 CPUs utilized
                90      context-switches                 #   20.572 /sec
                15      cpu-migrations                   #    3.429 /sec
             27493      page-faults                      #    6.284 K/sec
       33893694856      instructions                     #    2.07  insn per cycle
       16382153037      cycles                           #    3.745 GHz
        7015854946      branches                         #    1.604 G/sec
          58933691      branch-misses                    #    0.84% of all branches

       4.392140304 seconds time elapsed

       4.248055000 seconds user
       0.127881000 seconds sys
```

##### 从2到50000的埃氏素数筛的性能测试

测试代码如下：

```
import std;

func nsieve(n) {
    def count = 0;
    def arr = [n], i=0;

    while i < n {
        arr[i]=true;
        i += 1;
    }

    for i in range_ab(2, n - 1) {
        if arr[i] {
            count += 1;
            def j = i << 1;
            while j < n {
                arr[j] = false;
                j += i;
            }
        }
    }

    print("Primes up to ");
    print(n);
    print(" ");
    println(count);
}

def main = func {
    nsieve(50000);
}();
```

生成的原始结果分别如下：

```
# 优化前
 Performance counter stats for './stamon_2.4.53 run nsieve_2.4.53.stvc':

         698734500      task-clock                       #    0.983 CPUs utilized
                23      context-switches                 #   32.917 /sec
                 0      cpu-migrations                   #    0.000 /sec
              9682      page-faults                      #   13.856 K/sec
        5903937153      instructions                     #    2.23  insn per cycle
        2642267435      cycles                           #    3.782 GHz
        1239155201      branches                         #    1.773 G/sec
          12474872      branch-misses                    #    1.01% of all branches

       0.711171600 seconds time elapsed

       0.675939000 seconds user
       0.023856000 seconds sys
```

```
# 优化后
 Performance counter stats for './stamon_2.4.53 run nsieve_2.4.58.stvc':

         699443400      task-clock                       #    0.987 CPUs utilized
                23      context-switches                 #   32.883 /sec
                 0      cpu-migrations                   #    0.000 /sec
              9684      page-faults                      #   13.845 K/sec
        5903652717      instructions                     #    2.23  insn per cycle
        2647239011      cycles                           #    3.785 GHz
        1239098383      branches                         #    1.772 G/sec
          12481248      branch-misses                    #    1.01% of all branches

       0.708518398 seconds time elapsed

       0.660241000 seconds user
       0.040014000 seconds sys
```

##### 对优化前后的测试分析和结论

上述原始测试结果被数据提取并整理成了以下表格：

|测试项|优化前耗时（按秒计）|优化后耗时（按秒计）|
|:-|:-|:-|
|十万次空循环|0.207134601|0.153222000|
|朴素递归计算斐波那契数列第三十项|5.876182195|4.392140304| 
|从2到50000的埃氏素数筛|0.711171600|0.708518398|

在使用``stdc++``作为移植接口实现并对细节处进行优化后，stamon的性能在部分测试中得到了显著提升。