优化模组列表刷新性能:缓存解析结果与图标 - #6869
Open
xianaldai wants to merge 1 commit into
Open
优化模组列表刷新性能:缓存解析结果与图标#6869xianaldai wants to merge 1 commit into
xianaldai wants to merge 1 commit into
Conversation
Parsing a mod file opens its archive and reads its metadata entry, and every refresh of the mods directory repeated that work for every mod, even when nothing had changed. Parse each file once and cache the result keyed by its size and modification time, so a refresh of an unchanged directory only stats the files. Parsing also no longer runs on the manager lock, which lets the files be parsed in parallel on the first refresh. To make that possible the metadata readers return a new LocalModFile.Metadata value instead of a LocalModFile. A LocalModFile is bound to its manager and registers itself with the LocalMod it was created for, so it cannot be built off the manager lock nor reused across refreshes; the owning manager builds it from the parsed value when it merges the results. Two other things the parse phase was wasting time on: - ZipFileTree.getEntry falls back to indexing every entry of the archive whenever a name is absent, and the readers probe for optional entries constantly. Look those up in the reader's own name index instead. - A reload of the mod list rebuilds every item, so an icon held on the item was decoded again on the next reload. Hold the icons on the page, keyed by path, size and modification time, and let a rebuilt item reuse the icon already decoded for its file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
改动
解析一个模组要打开它的压缩包、读取元数据条目,而每次刷新都对每个模组重做一遍。现在按文件
大小和修改时间缓存解析结果,未改动的模组列表刷新只需一次
stat。为此读取器改为返回
LocalModFile.Metadata(新增的嵌套 record),而不是LocalModFile:后者绑定在管理器上、并把自己注册进对应的
LocalMod,无法跨刷新复用。读取器的方法名和参数顺序保持不变。
刷新会把每个
ModInfoObject重建一次,挂在条目上的图标于是被丢掉、下次再打开 jar 解一遍。改为把图标挂在页面上,以路径、大小、修改时间和加载器类型为键。
实测
268 个模组:
收益来自缓存:文件大小和修改时间未变时不再打开压缩包,每个模组只剩一次
stat。图标解码此前实测占刷新开销的绝大部分(29 个可见图标、589.6 ms),本 PR 让重建条目时复用
已解码的图标。