4

我本着 GoldenDict 的精神(www.goldendict.org,更多信息请参见 Google Play 商店)为 Firefox OS 编写了一个字典应用程序:http ://tuxor1337.github.io/firedict和https://marketplace.firefox。 com/app/firedict

由于 ffos 的应用程序基于 HTML、CSS 和 JavaScript(WebAPI 等),我必须从头开始编写所有内容。一开始,我用 JavaScript 写了一个用于同步和异步访问 StarDict 字典的基本库:https ://github.com/tuxor1337/stardict.js

尽管该应用程序现在可以称为稳定,但整体性能仍然有些迟钝。对于某些词典,我有一个包含近 1,000,000 个词条的单词列表!那是巨大的。索引需要很长时间(每个字典最多几分钟)和查找。目前,单词存储在 IndexedDB 对象存储中。还有其他选择吗?使用当前的解决方案(使用二进制搜索访问和插入的单词),整体体验非常缓慢。也许它会变得更快,如果 IndexedDB 有一些语言环境排序支持......实际上,我什至没有将术语本身存储在数据库中,而只是将它们的偏移量存储在 *.syn/*.idx 文件中。我希望这样做可以节省一些内存。但是当然我不能在这个配置中使用任何 IDB 排序功能......

也许在内存中进行排序不是最好的主意,因为现在由于某些设备(例如 ZTE Open)上的 OOM 导致应用程序被内核杀死。超过 500,000 个条目的字典肯定会超过 100 MB 的内存。(每个条目只有 200 字节,如果您认为关键字字符串是 UTF-8,那么您将立即超过 100 MB...)

随意直接为 GitHub 上的项目做出贡献。否则,我很高兴听到您对上述问题的建议。

4

1 回答 1

2

我正在研究与您的 stardict 项目类似的 MDict 解析器 ( https://github.com/fengdh/mdict-js ) 的纯 Javascript 实现。MDict是另一种流行的字典格式,格式丰富(嵌入图像/音频/css等),在window/linux/ios/android/windows手机上得到广泛支持。我有一些想法要分享,希望您将来可以将其应用于改进 stardict.js。

MDict字典文件(mdx/mdd)将关键字和记录分成(可选压缩)块,每个包含大约2000个条目,还提供关键字块索引表和记录块索引表,以帮助快速查找。由于其紧凑的数据结构,我可以直接在字典文件上实现我的 MDict 解析器扫描,具有较小的预加载索引表,但不需要 IndexDB

  • 每个关键字块索引如下所示:

    {num_entries: .., 
     first_word: .., 
     last_word: .., 
     comp_size: ..,    // size in compression 
     decomp_size: ..,  // size after decompression
     offset: ..,       // offset in mdx file
     index: ..
    }
    
  • 在 keyblock 中,每个条目是一对 [keyword, offset]

  • 每个记录块索引如下所示:

    {comp_size: ..,    // size in compression 
     decomp_size: ..,  // size after decompression
    }
    
  • 给定一个单词,使用二分搜索来定位可能包含它的关键字块。

  • 切片关键字块并加载其中的所有键,过滤掉匹配的一个并获取其记录偏移量。
  • 使用二分查找来定位包含单词记录的记录块。
  • 切片记录块并直接检索其记录(文本中的定义或 ArrayBuffer 中的资源)。

由于每个块仅包含大约 2000 个条目,因此在 100 毫秒内从 100K~1M 的字典条目中查找单词已经足够快,对于人类交互来说是相当不错的价值。mdict-js 仅解析文件头,它非常快且内存使用率低。

同样,即使使用通配符,也可以检索给定短语的相邻单词列表。

请在此处查看我的在线演示:http: //fengdh.github.io/mdict-js/ (您必须选择本地 MDict 字典:mdx + 可选 mdd 文件)

于 2014-08-04T01:45:41.327 回答