zoukankan      html  css  js  c++  java
  • 软件工程——数独 性能测试1

    一、    开发环境

    l  Windows10 版本号1903

    l  RAM 16GB 3200MHz 三星

    l  AMD Ryzen 7 2700X 3.90GHz

    l  SSD 三星 MZVLB1TOHALR-00000

    二、    文件读入

    在进行测试的过程中发现1e6的数据读入大概需要300秒,远远高于写入的6秒钟。显然由于硬盘限制写入时间应该大于读入,因此文件读入代码必然是有问题的,时间是不可接受的。

    原文件读入的代码如下:

    1. inline void mallocSudoku(Sudoku& s)  
      1. {  
      2.     if (s == nullptr)  
      3.     {  
      4.         s = new int* [10];  
      5.         for (int i = 0; i < 10; i++)  
      6.         {  
      7.             s[i] = new int[10];  
      8.         }  
      9. 10.     }  

    11. }  

    1. 12.   

    13. inline void freeSudoku(Sudoku& s)  

    14. {  

    1. 15.     if (s != nullptr)  
    2. 16.     {  
    3. 17.         for (int i = 0; i < 10; i++)  
    4. 18.         {  
    5. 19.             delete[] s[i];  
    6. 20.         }  
    7. 21.         delete[] s;  
    8. 22.         s = nullptr;  
    9. 23.     }  

    24. }  

    1. 25.   

    26. inline void readLineFromFile(char* line)  

    27. {  

    1. 28.     char* tmp = new char;  
    2. 29.     DWORD num_bytes_read = 0;  
    3. 30.     for (int i = 0; i < 9; i++)//依据约定,一行最多有9个数字  
    4. 31.     {  
    5. 32.         *tmp = 0;  
    6. 33.         while (*tmp < '0' || *tmp > '9')  
    7. 34.         {  
    8. 35.             if (ReadFile(h_sudoku_problem_txt, tmp, 1, &num_bytes_read, NULL) && num_bytes_read == 0)  
    9. 36.             {  
    10. 37.                 is_end = true;  
    11. 38.                 return;  
    12. 39.             }  
    13. 40.             //num_bytes_read++;  
    14. 41.         }  
    15. 42.         line[i] = *tmp;  
    16. 43.     }  
    17. 44.     delete tmp;  

    45. }  

    1. 46.   

    47. inline bool getSudokuFromFile(Sudoku s)  

    48. {  

    1. 49.     char* line = new char[9];  
    2. 50.     for (int i = 0; i < 9; i++)  
    3. 51.     {  
    4. 52.         readLineFromFile(line);  
    5. 53.         if (is_end)  
    6. 54.             return false;  
    7. 55.         for (int j = 0; j < 9; j++)  
    8. 56.             s[i + 1][j + 1] = line[j] - '0';  
    9. 57.     }  
    10. 58.   
    11. 59.     delete[] line;  
    12. 60.     return true;  

    61. }  

    1. 62.   

    63. //一次性读入一千个数独  

    64. inline void readSudoku()  

    65. {  

    1. 66.     for (int i = 0; i < BUFF_SIZE; i++)  
    2. 67.     {  
    3. 68.         Sudoku tmp = nullptr;  
    4. 69.         mallocSudoku(tmp);  
    5. 70.         if (getSudokuFromFile(tmp) == false)  
    6. 71.         {  
    7. 72.             freeSudoku(tmp);  
    8. 73.             return;  
    9. 74.         }  
    10. 75.         buff.push_back(tmp);  
    11. 76.     }  
    12. 77.     return;  
    13. }  
     

    分析代码,不难发现问题所在,那就是调用一次ReadFile只读入了一个字节的数据。原代码主要是考虑到可能的数独文件格式问题,通过再次阅读问题要求,发现数独问题文件格式是固定的,因此可一次读入163个字节(与输出一致)。由于最后一个数独的后面没有空行,因此读入的数据是162个字节,由此可以作为结束判断。另外一方面,可以一次性读入多个数独进行分析。若读入字节数小于163的整数倍,则已读完。经过一系列测试,代码修改如下:

    1. inline void toSudoku(char* tmp, DWORD& n_bytes_read)  
      1. {  
      2.     //由于读取时的限制,num_of_sudoku_in_buff <= BUFF_SIZE  
      3.     num_of_sudoku_in_buff = n_bytes_read / num_bytes_of_sudoku_infile;  
      4.     if (is_end)//因为结束时,向下取整,少了一个  
      5.     {  
      6.         num_of_sudoku_in_buff++;  
      7.     }  
      8.     for (int i = 0, j = 0; i < num_of_sudoku_in_buff; i++, j++)  
      9. 10.     {  
      10. 11.         Sudoku s = buff[i];  
      11. 12.         for (int row_idx = 1, col_idx = 1; j < (i + 1) * num_bytes_of_sudoku_infile - 1; j++, j++)  
      12. 13.         {  
      13. 14.             s[row_idx][col_idx++] = tmp[j] - '0';  
      14. 15.             if (col_idx == 10)  
      15. 16.             {  
      16. 17.                 row_idx++;  
      17. 18.                 col_idx = 1;  
      18. 19.             }  
      19. 20.         }  
      20. 21.     }  

    22. }  

    1. 23.   

    24. //一次性读入一千个数独  

    25. inline void readSudoku()  

    26. {  

    1. 27.     char* tmp = new char[num_bytes_of_sudoku_infile * BUFF_SIZE + 10];  
    2. 28.     ReadFile(h_sudoku_problem_txt, tmp, num_bytes_of_sudoku_infile * BUFF_SIZE, &n_bytes_read, NULL);  
    3. 29.     if (num_bytes_of_sudoku_infile * BUFF_SIZE > n_bytes_read)  
    4. 30.         is_end = true;  
    5. 31.     toSudoku(tmp, n_bytes_read);  
    6. 32.     return;  
    7. }  
     

    同时在文件读入修改中,将原先的vector更改为了数组形式,通过提前申请空间的方式减少了在获取数独和求解数独后释放数独空间的时间。

    在只更改文件读入方式的情况下,时间从300秒降到了11秒,在将vector更改为数独数组之后,减少了new 和 delete的时间,又降低到了8秒钟。

  • 相关阅读:
    Codeforces 401C Team 贪心法
    C++ 编译,执行过程 具体解释。
    [从头学数学] 第156节 概率初步
    关于flex,好像有12个属性非常重要
    数据清洗小记(12):姓与名的提取
    理解Angular中的$apply()以及$digest()
    Oracle开发者守则
    黑马程序猿——25,打印流,合并流,对象序列化,管道流,RandomAccessFile
    GPU 编程入门到精通(四)之 GPU 程序优化
    Python 面向对象编程 继承 和多态
  • 原文地址:https://www.cnblogs.com/harrypotterjackson/p/12201974.html
Copyright © 2011-2022 走看看