browser icon
You are using an insecure version of your web browser. Please update your browser!
Using an outdated browser makes your computer unsafe. For a safer, faster, more enjoyable user experience, please update your browser today or try a newer browser.

瓶颈

Posted by on 2010 年 12 月 27 日

你可以任意转载本文,但请在转载后的文章中注明作者和原始链接。
媒体约稿请联系 titilima_AT_163.com(把“_AT_”换成“@”)。

在开发漫画控 1.5.0 这个带有内置下载核心的版本时,我所设计的下载任务存储策略最初版本如下:

  1. 所有的漫画分卷(下载任务)都保存在一个数据表中;
  2. 每个分卷的分页 URL 各保存在一个单独的数据表中,每条记录为每页的 URL;
  3. 当每下载完一页后,更新 2 之中的记录,重写下载完成状态字段。

但是,这个未流出的版本在测试过程中却出现了很大的问题:当下载进行时,主界面会出现频繁卡顿的现象,而且网速越快时这种现象越发明显。
于是,我使用 Process Explorer 查看进程的信息,发现主线程的堆栈频繁出现在 SQLite 上(很可惜,当时没有截图留念)。也就是说,我最直接的瓶颈出现在更新分页记录的步骤 3 上。至于问题是出在 SQLite 的 step 操作上还是更底层的硬盘 I/O 上我倒不甚在意了,因为突破这两个问题的代价太大了——或者说,要么我修改 SQLite 的代码,要么我给我的用户更换硬盘。

我别无选择,只能修正我的存储策略,如下:

  1. 所有的漫画分卷(下载任务)都保存在一个数据表中;
  2. 为每个分卷记录增加一个 BLOB 字段,用于保存所有页面的 URL,采用 JSON 格式保存;
  3. 开始一个任务时,一次性读取 BLOB 字段中的 JSON 字符串,并将其解析到一个 array 之中;
  4. 每下载完一页后,只更新内存中 array element 的下载完成状态标志;
  5. 当任务下载完成后,将 array 重新序列化为 JSON 字符串,写入数据库之中。

订阅本站

4 Comments

  • At 2011.01.03 21:42, Магсн said:

    作为小白,求解释介绍 sqlite 为神马会卡

    • At 2011.01.04 09:14, 李马 said:

      根本原因是操作太频繁了,而执行一条 SQL 语句会包含很多复杂的操作,所以最终的结果是界面卡住。

      • At 2011.01.26 15:23, said:

        试过Sqlite的事务方式吗?

        在你的第三步开始后
        db.execDML(_T(“BEGIN TRANSACTION;”));

        ……操作数据库

        第五步
        db.execDML(_T(“COMMIT TRANSACTION;”));

        • At 2011.01.26 16:04, 李马 said:

          的确是个好办法。

          (Required)
          (Required, will not be published)