NodeJs 回调参数的最佳实践

Best Practice for Callback Parameters in NodeJs

背景

我是 Node.js 中 fast object traversal 的一个低级库的维护者。该库的重点是速度,并且经过了大量优化。然而,有一个很大的放缓:回调参数

问题

回调由图书馆消费者提供,每次扫描可以调用很多次。对于每次调用,都会计算所有参数并将其传递给回调。在大多数情况下,回调实际上只使用了一小部分参数。

目标

目标是消除这些参数的不必要计算。

解决思路

问题

这是一个非常基本的设计决定,我正在努力做到这一点。

非常感谢您的宝贵时间!一如既往的赞赏!

您可以向回调传递一个对象,该对象具有各种方法,使用回调的客户端可以调用这些方法来获取他们实际需要的任何参数。这样,您将拥有一个干净的对象接口,并且您将只计算实际请求的必要信息。

这种通用设计模式有时称为 "lazy computation",您只需根据需要进行计算。您可以使用访问器函数或 getter,具体取决于您要公开的接口类型。

出于性能原因,您或许可以在每次调用回调时重复使用同一个对象,而不是构建一个新对象(取决于您的实现细节)。

请注意,您甚至不必将计算所需的所有信息都放入对象本身,因为在某些情况下,对象上的方法可以在执行操作时引用您自己的本地上下文和本地范围的变量他们的计算。

However there is one big slowdown: Callback Parameters

你真的对这个进行了基准测试吗?我怀疑构建参数值的成本是那么高。请注意,如果这是一个非常频繁使用的调用,V8 可能会内联它,然后优化掉未使用的参数值。

Ideally NodeJs would expose the callback parameters as defined by the callback.

实际上,it does。如果你确实想依赖这个属性,你应该正确地记录你所做的,否则这个魔法可能会导致模糊的错误。

We could introduce a different callback for every parameter combination. This sounds like a bad idea.

提供两个选项 filter(key, value)filterDetailed(key, value, context) 似乎不是什么大问题。如果优化真的值得,而且正如你所说这是一个低级库,那就去吧。

Instead of passing in the parameters directly, we could pass in a function for each parameter that computes and returns the parameter value. Inside the callback the parameter would then be invoked as required. It's ugly but might be the best approach?

构造一个闭包对象来代替参数传递也确实有一些开销,因此您需要正确地对其进行基准测试。这可能不值得。

但是,我看到您实际上传递了一个上下文对象作为参数,在该对象上计算值作为属性进行访问。在这种情况下,您可以简单地使这些属性获取器在访问时计算值,而不是在构造对象时。