expl3 与传统 tex 的效率

expl3 与传统 tex 的效率

我开始欣赏 Latex3 expl 库,因为它提供了很好的抽象(例如字符串、列表……),但我也想创建一个尽可能高效的代码,因为它通常是我的瓶颈。在实践中,我经常混合使用遗留代码和 expl 代码,就像\def\mymacro\ifdefined\mymacro而不是\cs_set:Nn \mymacro: {}\cs_exist:NTF \mymacro:……所以我的问题如下:

总体而言,遗留代码是否比 expl 函数更高效?两者之间的差异有多大?例如,使用 是否\def比 更快\cs_set?我预计 expl 代码总是更慢,因为我预计它会首先扩展到遗留代码,但我可能错了。

举一个更具体的例子,wipet 提供了此代码,而我会自然地尝试使用标记列表和\tl_map_inline一些检查自己实现它,例如\if_cs_exist:w...他还重新创建了使用列表的概念,\addto而我会使用\seq(根据我的经验,构建起来效率很低,但也许我使用得不好?)...是否有可能在 LaTeX3 中创建同样高效的代码,还是应该坚持使用必须高效的部分的遗留代码?

更一般地说,我可以从 LaTeX3 中有效使用哪些结构?

混合使用旧代码和 expl3 代码可以吗?

答案1

任何抽象都会增加操作所需的时间。但是,绝对最大速度、代码灵活性和清晰度之间始终存在平衡。例如,expl3(例如)中的高级条件设置为可以处理两个分支中的任意材料。与(\tl_if_eq:NNTF相比,这对性能的影响不为零\if_meaning:w\ifx。但是,它是非常团队很少会担心这一点,即使是在相对低级的代码中。唯一使用“仅重命名原语”的地方是

  • 早期设置中 ( l3basics)
  • l3regex
  • l3fp

对于l3fpl3regex,需要团结起来“推动”TeX 意味着我们需要使用我们能用到的所有技巧。然而,这几乎不适用于其他任何地方。如果你想要一个极端的例子,数据类型在幕后tl使用:这比但允许标记慢得非常非常慢,而且它对现实世界的影响很小,我们更喜欢一致性而不是性能。\edef\<name>{\unexpanded{<content>}\def\<name>{<content>}#

作为更多“用户级”代码的示例,siunitx我并不太担心expl3在它们有用时使用更高级别的构造。我担心的是数据结构的性质。如果您查看 v3 代码,我使用prop用于收集单元:这些是具有多个部分的开放式列表,这种灵活的数据结构很有意义。但是,对于数字,我使用自定义方法:在内有固定数量的括号组tl。这在那里是有意义的,因为我可以进行“经典”参数数字操作来提取和添加材料。

还值得记住的是,我们在这里比较的是expl3经过数十年努力的代码(无论是团队直接编写的还是结合了 TeX 世界中的想法的)与您编写的原始代码。我自己的经验是,这expl3比我做过的随意编写的代码要好。在siunitx,v1 是慢点比 v2 更简单,尽管 v2 是内置的expl3,而 v1 没有:全部由我手工编码。现在,我可以(今天)利用所有经验expl3,自己编写每个循环、数据结构等,我使用:我考虑过这一点,这真是太麻烦了。

相关内容