性能分析
性能测试大概花了9、10个小时,快要赶上编码所需的时间了.很多时间不是花在编码上,而是寻找改进思路和查询文档上.
首版性能分析sudoku1.0
这一版花的时间最长,大概占了一半时间,是因为要对整个生成数独进行重构,而后几版只是局部优化.
对首版的sudoku1.0进行性能测试:
问题
发现在生成1000000个数独的情况下,生成的时间效率不高,尤其是使用dfs填入数字的时候.在查阅相关资料,发现了重大的算法实现问题.根据原来的算法,在基础一位数组的首位数字固定的情况下.使用这种算法,只能得到8!=40320个不重复的数独终局远小于1000000个.因此对CreateSudokuN函数及其内部的dfs函数进行重写.
解决方案
修改思路:在8!个数独的基础上进行行交换,在1个数独的基础上得到另外不同72个数独.
第一次改进后性能分析
这次的代码是正确的满足1000000个不重复数独的要求,但是花费时间还是很长24.935,只减少了2+秒.
问题
他的写文件fprint函数占用了86.96%的CUP.
查看网络上其他人的优化,发现是每一创建完新的数独就往文件里写入,会浪费很长的时间.
解决方案
于是决定将100万个数独矩阵先存入一个string变量中,最后在一次性写入文件.每个数独生成一个string,不断的合并入最终的写入string.
第二次改进后性能分析
发现这种方法有明显的改善,时间减少了58%.
问题
但是查看发现在GetArrystring中字符串string合并每一个数独,浪费了72.79%的时间
解决方案
将100万个矩阵存入一个char数组中,最后将这个char数组写入文件.
第三次改进后生成sudoku1.1性能分析
时间降到了6.164秒
问题
查看发现在现在fprintf已经降到了26.38%,这是占主要CPU的是Perm函数中生成基础数独的dfs,
解决方案
考虑对每一个基础DFS数独不止进行行交换,并且进行列交换的可行性.
第三次改进后生成sudoku1.2性能分析
时间已经将到了2.345秒.
问题
查看发现在现在Perm函数降到了24.97%,反而fprint又占最大比例71.49%,此时无法进一步对fprint降速.
解数独性能分析
解1e6个数独查看所需时间:
问题
发现用时26.444s,这是占主要CPU的是Solv函数解数独函数,无法进行优化.
解决方案
重构代码放弃DFS,可以考虑DLX,但是没有时间做出修改.
再一次整理规范细节得到最后一版sudoku1.3
修改一下输出格式问题