简体   繁体   English

TypeScript class function 作为 function 具有更好的性能

[英]TypeScript class function as function VS variable which has better performace

Is it better using variables which define a function or using a function in the first place?首先使用定义 function 或使用 function 的变量更好吗? Furthermore, is there a difference for tree-shaking?此外,摇树有区别吗?

I have a lot of calculation (static) intensive helper classes and was wondering what the best (memory/speed) is.我有很多计算(静态)密集型辅助类,想知道最好的(内存/速度)是什么。

Here the different ways I have in mind:这是我想到的不同方式:

 class MyClass { readonly functionA = (v: string | number, maxDeep: number, curDeep: number = 0): string => { if (curDeep < maxDeep) { return this.functionA(v, maxDeep, curDeep + 1); } else { return "function A" + v; } } static functionB(v: string | number, maxDeep: number, curDeep: number = 0): string { if (curDeep < maxDeep) { return MyClass.functionB(v, maxDeep, curDeep + 1); } else { return "function B" + v; } } functionC(v: string | number, maxDeep: number, curDeep: number = 0): string { if (curDeep < maxDeep) { return this.functionC(v, maxDeep, curDeep + 1); } else { return "function C" + v; } } static readonly functionD = (v: string | number, maxDeep: number, curDeep: number = 0): string => { if (curDeep < maxDeep) { return MyClass.functionD(v, maxDeep, curDeep + 1); } else { return "function D" + v; } } }

I tried using JSBen for measuring a difference but the results seem to be random.我尝试使用JSBen来测量差异,但结果似乎是随机的。 在此处输入图像描述

If you are that concerned about performance to optimize at this level, then having a class that only has static methods introduces some totally unnecessary overhead.如果您担心在此级别上优化性能,那么拥有仅具有 static 方法的 class 会引入一些完全不必要的开销。 Classes are designed to be instantiated, and if you don't use that feature you are wasting some computational resources to have those features available.类被设计为实例化,如果您不使用该功能,您将浪费一些计算资源来提供这些功能。

When I run your examples (MacOS, Chrome 90.0.4430.93) I get this:当我运行您的示例(MacOS,Chrome 90.0.4430.93)时,我得到了这个:

在此处输入图像描述

What's clear is that static methods have a large performance costs.显而易见的是,static 方法具有很大的性能成本。 Where instance methods are guaranteed to be fast.实例方法保证快速的地方。 I wish I could tell you why, but I'm sure it has something to do with the fact that classes are design to be instantiated.我希望我能告诉你原因,但我确信这与类被设计为实例化这一事实有关。


Much simpler than that, is a simple object.比这简单得多的是一个简单的 object。 Let's add these two tests:让我们添加这两个测试:

const obj = {
  functionE(v, maxDeep, curDeep = 0) {
    //...
  },

  functionF: (v, maxDeep, curDeep = 0) => {
    //...
  }
};

在此处输入图像描述

Those run just about as fast as the instance methods.它们的运行速度与实例方法一样快。 And it's a pattern that makes more sense.这是一种更有意义的模式。 There's no classes because there is no instantiation.没有类,因为没有实例化。


But there's an even simpler alternative:但是还有一个更简单的选择:

function rawFunctionStatementG(v, maxDeep, curDeep = 0) {
  //...
}

const rawFunctionVarH = (v, maxDeep, curDeep = 0) => {
  //...
};

在此处输入图像描述

Performance wise, we have a winner here.性能方面,我们在这里有一个赢家。 I'm fairly sure this is because you never have to look up a property on an object.我很确定这是因为您不必在 object 上查找属性。 You have a reference to the function directly, and can execute it without asking any other object where to find it first.您有对 function 的直接引用,并且可以执行它而无需询问任何其他 object 先在哪里找到它。

Updated jsben.ch更新了 jsben.ch


And as far as tree shaking, this form is by far the best.就摇树而言,这种形式是迄今为止最好的。 It's easiest for bundlers to manage whole exported values, rather than trying to slice and dice individual objects.捆绑器最容易管理整个导出的值,而不是尝试对单个对象进行切片和切块。

If you do something like:如果您执行以下操作:

// util-fns.ts
export function myFuncA() { /* ... */ }
export function myFuncB() { /* ... */ }

// some consumer file
import { myFuncA } from './util-fns'

Then it's super easy for a bundler to see that myFuncB is never imported or referenced, and could be potentially pruned.然后,捆绑器非常容易看到myFuncB从未被导入或引用,并且可能会被修剪。


Lastly...最后...

“The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; “真正的问题是程序员在错误的地方和错误的时间花费了太多时间来担心效率; premature optimization is the root of all evil (or at least most of it) in programming.”过早的优化是编程中万恶之源(或至少大部分)。” – Donald Knuth ——唐纳德·克努斯

It's very unlikely for performance optimizations of this level to matter in the vast majority of javascript applications.绝大多数javascript 应用程序中,这种级别的性能优化不太可能产生影响。 So use the data structures that make the most sense for the application, and according to the standards of the codebase/organization.所以使用对应用程序最有意义的数据结构,并根据代码库/组织的标准。 Those things matter so much more.这些事情比这更重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM