lodash的“ get”和“ if else”子句之间的性能差异

时间:2019-03-20 17:39:20

标签: javascript json typescript lodash benchmarking

假设您有一个打字稿对象,其中任何元素都可以为undefined。如果要访问高度嵌套的组件,则必须对undefined进行很多比较。

我想比较两种执行此操作的方法:常规的if-else和lodash函数get

我发现了一个名为 jsben 的漂亮工具,可以用来对不同的js代码段进行基准测试。但是,我无法正确解释结果。

在此test中,lodash get似乎要快一些。但是,if I define my variable in the Setup block(与Boilerplate code相反),if-else代码的速度要快得多。

对所有这一切进行基准测试的正确方法是什么? 我应该如何解释结果? 尽管可读性很差,get的速度这么慢,以至于您可以主张使用if-else子句吗?

2 个答案:

答案 0 :(得分:2)

我认为您是在问错问题。

首先,如果要进行性能微优化(与算法优化相对),则应该真正知道所讨论的代码是否是系统中的瓶颈。修复最严重的瓶颈,直到性能良好为止,然后再不用担心太多了。如果在严肃的应用程序中,两者之间的差异超过舍入误差,我会感到非常惊讶。但是我以前很惊讶;因此需要测试

然后,当涉及到实际优化时,在两种配置中,两种实现的速度仅稍有不同。但是,如果您要测试对对象的深度访问,则看起来第二个对象是思考它的正确方法。似乎它不会在相对速度上产生很大差异,但是第一个代码将初始化代码放在将“在每个块之前执行,并且是基准的一部分”的位置。第二个是“它将在每次测试之前运行,并且不是基准测试的一部分”。由于您要比较数据访问而不是数据初始化,因此这似乎更合适。

鉴于此,families && families.Trump && families.Trump.members && ...技术似乎在性能上有很小的优势。 (请注意:这里看不到ifelse!)

但是值得吗?我不会说。代码非常丑陋。我不会添加诸如lodash(或我最喜欢的Ramda)之类的库只是为了使用像这样简单的函数,但是如果我已经在使用lodash,那么我会毫不犹豫地在这里使用简单的代码。而且我可能会从lodash或Ramda导入一个,或者直接编写自己的代码,因为这是相当简单的代码。

本机代码将比更通用的库代码更快,这不足为奇。它并非总是会发生,因为有时库会采用本机引擎无法采用的快捷方式,但这很可能是常态。使用这些库的原因很少与性能有关,而是与编写更具表现力的代码有关。在这里,lodash版本会赢得胜利,请放手。

答案 1 :(得分:1)

  

对所有这一切进行基准测试的正确方法是什么?

仅对要比较的实际代码进行基准测试,并尽可能将其移出测试块。将这两部分中的每部分运行几千(上千)次,以求平均其他部分的影响。

  

我应该如何解释结果?

1)检查它们是否有效:

结果符合您的期望吗? 如果没有,那可能是有原因的吗? 测试用例是否可以复制您的实际用例?

2)检查结果是否相关:

花费的时间与用例中的实际时间相比如何?如果您的代码需要200毫秒的加载时间,并且两个测试都在〜1毫秒内运行,则结果无关紧要。但是,如果您尝试优化每秒运行60次的代码,那么1ms已经足够了。

3)检查结果是否值得工作

通常您必须进行大量的重构,或者必须进行大量的输入,性能提高的时间是否超过您的投资时间?

  

速度慢了很多,尽管可读性很差,但您仍然可以使用if-else子句进行争论?

我会拒绝。使用_.get(除非您打算每秒运行数百次)。