北京理工大学2019软件工程个人项目-数独-04

本开发周期实现并完善了Sudoku类和SudokuGenerator类。

0. GitHub项目地址

本项目对应的GitHub代码仓库点此进入

4. 软件实现

在软件实现阶段,我们将实现第三章所述程序设计。

4.1 实现Sudoku类

根据前述软件设计,在Sudoku类中,有如下成员:

  • 变量
    • int[][] data 保存当前数独的局面。
  • 方法
    • Sudoku(const int[][] = NULL) 构造函数,初始化数独
    • Print():void 将数据输出至控制台
    • PrintToFile(const String& fileName): void 向特定文件输出数独
    • operator=(const Soduku&):Soduku 重载赋值运算符
    • Sudoku(const Soduku&):Soduku 重载拷贝构造函数
    • ~Sudoku() 重载析构函数

Sudoku类的实现已签入github。

4.2 实现SudokuGenerator类

根据前述软件设计,在SudokuGenerator类中,有如下成员:

  • 变量
    • String outputFile 指示生成的数独应当输出到哪个文件
    • int sodukuNum 指示生成的数独个数
    • Sudoku* Sudokus 存放生成的数独
  • 方法
    • SudokuGenerator(String outputFile, int sodukuNum) 构造函数
    • GenerateSudoku():void 生成数独
    • ValidateInput(const String[] parameters) :bool 验证输入是否有效
    • GenerateBaseSoduku(int num):void 生成基础数独,基础数独的定义见开发日志3
    • ExpandSoduku():void

Sudoku类的实现已签入github。

6. 性能改进

6.1 SudokuGenerator类

主程序如下图。
在这里插入图片描述
运行VS2019 性能分析工具,结果如下图。
在这里插入图片描述
在这里插入图片描述
可见fclose函数是所有函数中占用时间最长的,其调用次数也远远超过其他热点函数。由于这是一个系统函数,我们无法进行优化,因此我们试图减少它的调用次数。分析程序可知,由于模块间及模块内部传递文件信息时使用的是文件名,因此对每一个基础数独,我们都需要打开、关闭一次文件指针。因此,我们改用传递文件指针。这样就可以避免频繁地打开关闭文件。

据此对Sudoku类和SudokuGenerator类进行重构。由于用户仅可见SudokuGenerator类,我们仅保留SudokuGenerator的构造函数使用字符串传递文件名,其余的接口全部改用文件指针传递文件信息。

重构后,再次运行性能分析工具,结果如下。
在这里插入图片描述
可见运行时间大大降低,生成100万组数据用时降低91.88%。查看调用树如下。
在这里插入图片描述
发现用数最多的函数为Sudoku类的构造函数中的new运算。分析后发现,这里并无动态分配内存的必要,因此改用静态分配内存。同时,并不需要为每一个输出的数独一个Sudoku对象,仅需为基本数独产生即可。进行修改,再次运行性能分析工具。结果如下。
在这里插入图片描述
可见此时new运算已经不再是热点,生成100万组数据用时4.581s,且主要花费在磁盘IO上。本次改进是的性能再次提升33.906%,相比最初版本运行时间降低94.631%。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值