目录
性能分析
在实现了数独项目基本功能的基础上,我们使用Visual Studio集成的性能探查器对项目的性能进行分析,从各方方面包括文件的读写问题、字符串的处理上进行改进。
初步分析
在编码阶段,查阅相关资料时,了解到文件读写会是一个占用时间比较长的问题。于是在编码时就考虑到这个问题。首先我分4个方面去进行测试:
-
逐字符写入文件
-
逐数独写入文件
-
以30个数独为单位写入文件
-
全部数独一次性写入文件
逐字符写入 | 逐数独写入 | 以30个数独为单位写入 | 全部数独一次性写入 | |
---|---|---|---|---|
1000(个) | 203ms | 100ms | 16ms | 16ms |
10000(个) | 1859ms | 956ms | 262ms | 234ms |
1000000(个) | 13000ms | 13044ms |
分析上述时间发现一次性写入1000000个数组时时间反而变长,于是猜想可能是过大的数组在初始化时耗时较长,于是测试memset时间,如下:
数组大小 | memset 时间 |
---|---|
char [10000] | 1ms |
char [1000000] | 230ms |
分析时间后,发现按照最快速度,生成1000000个数独,时间消耗还是很长,于是研究其他c++文件读写方式,发现并不能很好的提高速度。
VS性能分析
使用visual studio2017进行性能分析,由于项目需求里只对数独生成功能有性能要求,于是关于项目的性能优化及分析主要针对数独生成部分,即generate_final 函数。
第一次分析
在分析报告中发现,一个简单的赋值语句竟然是耗时最多的部分。这句话是用来对由第一句经过全排列加平移构成的数独进行交换行的操作。但是还是不清楚为什么耗时这么长,首先怀疑是swap_line[s][j] 嵌套的原因,于是修改后再进行性能分析。
第二次性能分析
将套拆分出来后,性能还是没有改变,在意料之中。于是猜想是string类的原因,此处的all[][]二维数组是string 类型,可能会出现耗时过大的问题,于是将全部string类改为 char类型,并将string的函数手动用char类型实现。
第三次性能分析
再次进行性能分析,发现将全部string类改为 char类型后这里的时间耗费减小了很多,可以达到要求。
但是文件写入便成为耗时最大的部分,占整个函数的72.68%
为了减少文件写入次数,我尝试采用不同个数的独为单位进行读写,一下为测试3次取平均值,如图:
文件写入的占比 | 文件写入时间(1e6) | memset占比 | |
---|---|---|---|
60个 | 71.24% | 2043ms | <0.05% |
300个 | 69.43% | 2005ms | <0.05% |
可以发现,性能的优化不明显,且随着数组的增大程序执行所消耗的内存便会增大,所以仍然以60个数独作为单位进行写入文件。
我再次尝试使用其他文件读写方式进行测试,使用fputs进行文件写入
文件写入的占比 | 文件写入时间(1e6) | memset占比 | |
---|---|---|---|
60个 | 69.89% | 2104ms | <0.05% |
性能效果和使用ofstream差异不明显。
最终性能分析图
最终程序里花费时间最多的是文件的读写,其次是字符的赋值操作。
问题收获:
开始在使用visual studio做性能分析时,遇到了问题。于是我先进行了不同输入方式程序运行的时间,没有进行性能分析测试,所以在之前的比较中可能会有细微的差异。在做性能分析后,发现花费最多的竟然是string字符串的处理,所以在之后的项目实践中,在写好最初版本后,先进行性能分析,然后有针对性的进行优化,而不是凭经验优化。
其他博客: