【发布时间】:2021-12-16 09:37:07
【问题描述】:
我正在通过构建一些基本的遗传学功能来修补 Rust,例如读取包含 DNA 序列的文件,将其转录为 RNA,将其翻译为氨基酸序列等。
我希望这些转换中的每一个都接受和返回迭代器。这样我就可以将它们串在一起(如dna.transcribe().traslate()...)并且只在必要时收集,因此编译器可以优化整个转换链。我是一名来自 Scala/Spark 的数据科学家,所以这种模式很有意义,但我不确定如何在 Rust 中实现它。
我已经阅读了this article about returning iterators,但最终的解决方案似乎是使用 trait 对象(可能会对性能产生很大影响),或者手动滚动带有关联结构的迭代器(这允许我返回一个迭代器,是的,但我不明白它如何让我编写一个也接受迭代器的转换)。
这里有什么一般的架构建议吗?
(仅供参考,到目前为止我的代码是available here,但我觉得我并没有习惯性地使用 Rust,因为 a. 仍然无法完全编译 b. 这种惰性链接操作模式意外导致复杂而凌乱的代码,只能在 Rust nightly 上运行。)
【问题讨论】:
-
你怎么知道装箱迭代器是一个性能问题——你实际测量过吗?人们倾向于说返回一个装箱的迭代器会影响性能,它确实可以阻止一些优化的发生(例如激进的内联),但请记住,可怕的“动态调度”实际上是一个指针读取 + 跳转。 (这不像 Python 中的 dict 查找。)如果您对每个项目执行任何实质性操作,您将永远不会注意到调度。确保您没有在解决非问题上投入大量精力 - 唯一确定的方法就是衡量。
-
@user4815162342 是的。这就是说我使用迭代器的全部原因是为了提高性能(如我问题的第一段所述)。我想看看将迭代器链接在一起是否比链接接受和返回向量的函数更好(每个函数中都有一个
collect)。到目前为止,迭代器模式较慢,即使没有动态调度。