【个人项目数独】5、性能分析与改进

性能分析

生成总局

生成1000000个数独时的性能分析图:
在这里插入图片描述
查看函数消耗情况:

在这里插入图片描述
由于在编码时已经采用了比较节省时间的方式,比如把第一行的40320种情况全都预先储存起来,以及在各行交换生成多种终局时手动记录下要交换的行的索引,因此生成一百万个数独终局累计耗费17余秒,已经算是不错的结果。目前通过性能分析图可以看到,主要的时间花费在了写入文件的的fprintf函数上,因此考虑对此进行优化。首先我想到的是将逐个输出改为一次输出一整行的形式,即由

for (int j = 0; j < 9; j++)
{
   if (j == 0)
     fprintf(fp, "%d", grid.map[i][j]);
   else
     fprintf(fp, "%c%d", ' ', grid.map[i][j]);
}

改为

fprintf(fp, "%d %d %d %d %d %d %d %d %d\n", grid.map[i][0], grid.map[i][1], grid.map[i][2], grid.map[i][3], grid.map[i][4], grid.map[i][5], grid.map[i][6], grid.map[i][7], grid.map[i][8]);

后经测试效率确实有了一些提升,但是这时我又了解到fwrite函数,由于其是以二进制的形式对文件进行操作,效率比fprintf要高很多,于是我打算改用fwrite进行写入文件。
于是代码变为:

  for (int j = 0; j < 9; j++)
  {
   char temp=(grid.map[i][j]+'0');//将整型转为字符型以便用fwrite输出
   if (j == 0)
    fwrite(&temp, 1, 1, fp);
   else
   {
    fputc(' ',fp);
    fwrite(&temp, 1, 1, fp);
   }
  }

效果提升明显,改进后的性能情况如下:
在这里插入图片描述
可以看到,采用了fwrite函数对输出进行优化之后,效率提升了近三倍,仅6秒多就完成了生成一百万个数独终局的任务。

求解数独

求解1000000个数独题目耗时如下:
在这里插入图片描述
由于在编码时已经采用了较为高效率的方式,比如在检查行/列/宫中的数字时采用位运算来加快速度,以及进行DFS操作时采用指针引用技术来避免内存复制而导致的低效率问题,所以可以看到解1000000个数独题目耗时约两分钟,主要花费时间在DFS上,这里毕竟算法复杂度在那摆着呢,也没办法再有什么很大的提升了。

未来方向

在生成终局部分仍然是写入文件的函数消耗了大多数的时间,但fwrite毕竟是系统函数,难以进行优化,后续或许可以考虑尝试由操作系统提供的文件操作API进行读写操作以将速度进一步提升。
在求解数独部分DFS算法消耗了大多数的时间,若对其进行优化就应当考虑采用更高效率的算法诸如舞蹈链等。
另外读文件的部分也可以进行再优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值