问题描述
我正在使用shake
编写静态网站构建器,并试图实现一种效率的方式来持久化网站的导航(以及每个页面的一些元数据)。事实证明,这比我想象的要复杂:
- site-Metadata是一个树型数据结构,其中树中的每个节点都是一个永久链接,以及页面的元数据,例如标题,简短的摘要,作者等。
- 几乎所有页面都使用此站点元数据来呈现站点范围的导航(在标题或边栏中)。
- 只要修改页面,其构建规则就会修改其在站点元数据中的节点。
- 完整的网站元数据存储在一个文件中(而不是每个页面的元数据中的单个文件)
如果在每个页面的构建操作结束时对站点元数据进行了更新,则将导致对站点元数据进行反序列化,更新,序列化并写入磁盘,这可能会进行数百次(一次用于oeach build-规则)。
相反,我正在考虑将站点元数据读取到最顶部的IORef
中,并在每个页面的构建操作结束时更新内存IORef 。
但是,这可能导致两个问题:
如果我使它变得更复杂了,那么实现此目标的另一种有效方法是什么?
解决方法
首先,在进行优化之前,可能有必要仔细检查一下序列化等昂贵的假设。在很多情况下,这不是问题。但是让我们假设它太昂贵了。
最大的问题是循环依赖性。如果可以设计出来的话,Shake中有很多解决方案可以避免重复序列化等。我宁愿考虑将依赖项设计为:
- 每个页面分别生成其元数据。
- 一个从所有页面收集所有元数据的规则,这取决于步骤1中的每个规则。
- 每个页面取决于其自己的元数据以及根据2收集/汇总的元数据。
现在,您已经消除了循环。您还导致规则2仅聚合/序列化一次。
但是您仍然需要多次反序列化,这可以通过newCache
消除,它可以引入对文件反序列化形式的依赖性-规则仍然取决于文件,但是通过应用转变。
最后一点,如果采用上述公式,您可能希望第2步直接生成侧边栏/顶部栏内容,然后也可以共享所有渲染这些功能的工作。