查看: 644|回复: 7
打印 上一主题 下一主题

[讨论] 词典软件如何做到在几百个MDX中瞬间就找到了要检索的单词

[复制链接]
  • TA的每日心情

    2019-9-23 23:38
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    238

    主题

    552

    回帖

    4万

    积分

    禁止发言

    积分
    47766
    跳转到指定楼层
    1
    发表于 2020-4-1 12:23:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    象欧路这种软件,即使同时打开几百个甚至上千个MDX,只要这个单词在每部词典中需要渲染的内容少(比如生僻词)又没有什么复杂的JS,最后渲染出来的时间都只是区区几秒钟。看起来从每个MDX中找到要检索的单词加起来的总时间(我只是谈检索找到的总时间而不是渲染的总时间)几乎是可以忽略不计的。

    我感到这个速度非常神奇!

    MDX具有极高的压缩率,解压出来的原始文本HTML文件暴涨5倍以上体积是很常见的。几百个MDX原始文件大小加起来可能有十几或者几十GB,如果要全部解压可能是几十GB甚至上百GB。显然词典软件不可能将所有MDX解压到硬盘或内存中。看起来MDX全部解压出来之后再读取有效内容并检索并非是这些词典软件的做法。然而令人疑惑的是,即使它们可以不用解压而可以直接读取MDX(或者不事先全部解压而是每次只读一小部分就立即解压一小部分),这也是惊人的速度!十几GB或者几十GB的MDX从硬盘中读取到内存的总时间绝对不可能是区区几秒的瞬间过程。如果用windows资源管理器查看词典软件内存占用,它们不过占用区区几MB或者十几MB,几十MB的内存,看起来它们根本不会将这些MDX从硬盘全部(不管是全部一次还是分多次)读取到内存中处理?

    MDX无需读取全部内容就能从其中特定的位置检索出某个特定单词?? 看起来这只有事先对MDX进行索引才能做到!

    GOLDENDICT每次加入新MDX的确有一个预处理(索引?)过程,但是我不能确定这个过程就是完全针对我们正在探讨的单词在MDX中检索的这个问题的?
    进一步,欧路这种软件看起来根本就不会去做GOLDENDICT这个索引,尽管它也会有个预处理,但这个预处理时间和GOLDENDICT比小好几个数量级。通过查看欧路预处理生成的文件可以发现主要是为了避免不同词库的冲突而对CSS的处理,与其说欧路是在对MDX预处理,不如说是在对(MDD中的)CSS预处理。这从它的处理时间就可以看出来,显然远比全部读出所有MDX(甚至再加上解压)的总时间小几个数量级:即使安装了几百个MDX,清缓存将生成的预处理文件全部删除,下次再重新启动欧路,也不过是十秒上下的时间就启动和处理完毕在待命了。

    再者,做索引的前提条件是不是MDX中的单词要按字母顺序排列呢??然而MDX规范中应该没有这个要求吧?即使不按字母顺序排列的MDX应该一样可以正常和不减速地使用呢?



    有高人能稍微解释一下吗?

  • TA的每日心情

    2020-4-2 00:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    2

    主题

    36

    回帖

    991

    积分

    举人

    Rank: 4

    积分
    991
    推荐
    发表于 2020-4-1 14:17:41 | 只看该作者
    本帖最后由 last_idol 于 2020-4-1 14:55 编辑

    mdx支持lzo和zip这两种压缩算法,常用的是标准的zip压缩,和你平时压缩文件没区别,只是mdx只处理文本,所以压缩率是很高的,这里有对比,相比新出的几个压缩算法也不弱,就是解压速度慢点。https://facebook.github.io/zstd/
    goldendict的预处理,其实就是先读取所有数据的地址,这里面会计算数据在压缩块里的位置和压缩块相对于整个文件的位置,然后建立索引,后面查词的时候就可以直接从这个地址里读取数据了,不需要加载整个文件,goldendict这里用的mmap,可以直接从内存读取文件数据,速度更快,实测goldendict读取一条记录速度在50~300微秒之间,这还是在调试没有优化性能的情况下。在mdx里一个压缩块解压后是64KB,每次只读取这么多就够了。读取100本mdx的数据,总共也就6400KB,所以速度很快的,内存占用也不高。

    对于索引每家软件都不一样,
    mdict应该是直接读取的mdx本体里的索引,没有自行处理,所以mdx里的词头顺序会影响搜索结果。
    欧路实测好像也是和mdict一样,用的mdx本体索引,但看别人解包欧路,里面有goldendict的源码痕迹,搞不清用的什么索引。
    goldendict用的Btree索引,数据库常用算法,除检索速度优势外,插入数据不需要考虑顺序,而且因为是自建索引,所以也不受mdx本体词头顺序的影响。

    goldendict的数据还是半年前的印象了,论坛里nonwill改版优化过的goldendict性能更好。





  • TA的每日心情
    开心
    2019-10-10 05:35
  • 签到天数: 328 天

    [LV.8]以坛为家I

    12

    主题

    2675

    回帖

    4万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    46073
    3
    发表于 2020-4-1 14:34:29 | 只看该作者
    真是爱学习爱钻研的小朋友,为你点赞!
  • TA的每日心情
    慵懒
    2021-9-28 14:33
  • 签到天数: 158 天

    [LV.7]常住居民III

    5

    主题

    907

    回帖

    1万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    17310

    QQ 章灌水大神章笑傲江湖章推广专家

    4
    发表于 2020-4-1 18:08:15 | 只看该作者
    last_idol 发表于 2020-4-1 14:17
    mdx支持lzo和zip这两种压缩算法,常用的是标准的zip压缩,和你平时压缩文件没区别,只是mdx只处理文本,所 ...

    nonwill没改过goldendict的排序算法。
  • TA的每日心情

    2020-4-2 00:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    2

    主题

    36

    回帖

    991

    积分

    举人

    Rank: 4

    积分
    991
    5
    发表于 2020-4-1 18:25:04 | 只看该作者
    atauzki 发表于 2020-4-1 18:08
    nonwill没改过goldendict的排序算法。

    嗯,排序应该还是原版的,主要是并发加载这块,我这之前启动要20秒,还经常启动不起来,换他的5秒不到。
  • TA的每日心情
    开心
    2020-4-10 00:58
  • 签到天数: 77 天

    [LV.6]常住居民II

    8

    主题

    305

    回帖

    1万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    18518

    灌水大神章笑傲江湖章QQ 章

    6
    发表于 2020-4-1 20:41:31 | 只看该作者
    个人使用时的感受是同样调取65本左右的常见词典mdx查词,欧路的查词速度快于goldendict(包括最近论坛里的优化改版本)
  • TA的每日心情

    2020-4-2 00:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    2

    主题

    36

    回帖

    991

    积分

    举人

    Rank: 4

    积分
    991
    7
    发表于 2020-4-1 22:53:10 | 只看该作者
    本帖最后由 last_idol 于 2020-4-1 22:54 编辑
    nonwill 发表于 2020-4-1 22:28
    查询速度并不会比着欧陆慢,慢主要慢在词典列表的刷新上。
    因为应用词典分组可以较好的解决这个问题,所 ...

    我也觉得可以直接出列表,不需要JS去刷新。查词大家都差不多,慢个50毫秒其实都没啥感觉,真正会卡的地方还是浏览器本身。
  • TA的每日心情
    奋斗
    2019-10-11 13:52
  • 签到天数: 142 天

    [LV.7]常住居民III

    15

    主题

    336

    回帖

    15万

    积分

    状元

    Rank: 9Rank: 9Rank: 9

    积分
    153139

    灌水大神章小蜜蜂章笑傲江湖章推广专家QQ 章

    8
    发表于 2020-4-2 18:59:28 | 只看该作者
    用 mdxBuilder 打包的时候,mdxBuilder 会对词头排序。