解构变量性能

问题描述 投票:0回答:4

写入之间是否存在性能差异(如果有)

const color = props.color;

const { color } = props;

此外,如果我们在参数签名中进行解构,我们是否会获得或损失任何性能?参见示例3

我认为在这种情况下 example3 是编写该函数的最佳方式?


功能反应组件示例:

const example1 = (props) => {
  const color = props.color;
  // I know I could also just write style={{ color: props.color }}
  // but for arguments sake lets say I want to write it like this.
  return <h1 style={{ color }}>Hello</h1>;
};

const example2 = (props) => {
  const { color } = props;
  return <h1 style={{ color }}>Hello</h1>;
};

const example3 = ({ color }) => {
  return <h1 style={{ color }}>Hello</h1>;
};
javascript reactjs ecmascript-6 destructuring
4个回答
37
投票

编译器/转译器不一定总是删除解构赋值,因为截至 2020 年,所有常青浏览器都原生支持解构。据统计,有一些证据表明,至少截至 2018 年,V8 中通过解构赋值生成的字节码要多得多。比传统函数参数更详细:

功能参数:

function add(number1, number2){
  return number1 + number2;
}
const result = add(1,5);

输出字节码:

[generating bytecode for function: add]
Parameter count 3
Frame size 0
   74 E> 0x2a2a0affd2a2 @    0 : 91                StackCheck 
   96 S> 0x2a2a0affd2a3 @    1 : 1d 02             Ldar a1
  111 E> 0x2a2a0affd2a5 @    3 : 2b 03 00          Add a0, [0]
  121 S> 0x2a2a0affd2a8 @    6 : 95                Return 
Constant pool (size = 0)
Handler Table (size = 16)

解构作业:

function add({number1, number2}){
  return number1 + number2;
}
const result = add({number1: 1, number2: 5});

输出字节码:

[generating bytecode for function: add]
Parameter count 2
Frame size 40
   74 E> 0x2c1d63b7d312 @    0 : 91                StackCheck 
         0x2c1d63b7d313 @    1 : 1f 02 fb          Mov a0, r0
         0x2c1d63b7d316 @    4 : 1d fb             Ldar r0
         0x2c1d63b7d318 @    6 : 89 06             JumpIfUndefined [6] (0x2c1d63b7d31e @ 12)
         0x2c1d63b7d31a @    8 : 1d fb             Ldar r0
         0x2c1d63b7d31c @   10 : 88 10             JumpIfNotNull [16] (0x2c1d63b7d32c @ 26)
         0x2c1d63b7d31e @   12 : 03 3f             LdaSmi [63]
         0x2c1d63b7d320 @   14 : 1e f8             Star r3
         0x2c1d63b7d322 @   16 : 09 00             LdaConstant [0]
         0x2c1d63b7d324 @   18 : 1e f7             Star r4
         0x2c1d63b7d326 @   20 : 53 e8 00 f8 02    CallRuntime [NewTypeError], r3-r4
   76 E> 0x2c1d63b7d32b @   25 : 93                Throw 
   76 S> 0x2c1d63b7d32c @   26 : 20 fb 00 02       LdaNamedProperty r0, [0], [2]
         0x2c1d63b7d330 @   30 : 1e fa             Star r1
   85 S> 0x2c1d63b7d332 @   32 : 20 fb 01 04       LdaNamedProperty r0, [1], [4]
         0x2c1d63b7d336 @   36 : 1e f9             Star r2
   98 S> 0x2c1d63b7d338 @   38 : 1d f9             Ldar r2
  113 E> 0x2c1d63b7d33a @   40 : 2b fa 06          Add r1, [6]
  123 S> 0x2c1d63b7d33d @   43 : 95                Return 
Constant pool (size = 2)
Handler Table (size = 16)

字节码行数从函数参数情况下的 4 行显着增加到解构赋值情况下的 19 行。总之,截至 2018 年 V8 中,解构赋值的计算效率低于传统函数参数。就内存空间利用率而言,答案有点复杂,可以参考here

这可能是一个过早的优化,但是在计算量大的代码中,建议考虑不使用解构分配。


6
投票

不会有任何性能问题,因为您的代码将被编译/缩小等。

请注意,使用 React,您的代码将被转译,其作用与

相同

const color = props.color

babel编译器在线测试器上查看结果


0
投票

捆绑包大小对于 JavaScript 性能也很重要,并且解构变量在某些情况下有一些注意事项,特别是当它们是函数参数时。

第一个没有对象解构的示例

function add(number1, number2){
  return number1 + number2;
}
const result = add(1,5);

结果

function add(d,n){return d+n}const result=add(1,5);

输入:86字节;输出:51字节;压缩:40.7%,节省:35字节;

对象解构的第二个示例

function add({number1, number2}){
  return number1 + number2;
}
const result = add({number1: 1, number2: 5});

结果

function add({number1:n,number2:r}){return n+r}
const result=add({number1:1,number2:5});

输入:109字节;输出:87字节;压缩:20.18%,节省:22字节;

第三个例子,使用对象但不解构

function add(opts){ 
  const number1 = opts.number1; 
  const number2 = opts.number2; 
  return number1 + number2; 
}

add({number1: 1, number2:5});

结果

function add(n){return n.number1+n.number2}add({number1:1,number2:5});

输入:148字节;输出:70字节;压缩:52.7%,节省:78字节;

结论

在所有情况下,对象解构是最糟糕的包大小,因为它无法优化对象的名称(也许有一个我忘记的选项)。我个人的意见是关注可维护性和可读性。我觉得如果你让你的代码变得更糟,这些微小的改进就不值得。

奖励:变量实例化(超出范围)

在某些情况下,从包大小的角度来看,对象解构更好。当你初始化变量时。

无对象解构

const obj = {username:"name",lastname:"lastname",age:20};
console.log('break minify optimization');
const username = obj.username;
const lastname = obj.lastname;
const age = obj.age;

结果

const obj={username:"name",lastname:"lastname",age:20};console.log("break minify optimization");const username=obj.username,lastname=obj.lastname,age=obj.age;

输入:182字节; 输出:158字节; 压缩率:13.19%, 节省:24字节;

具有对象解构

const obj = {username:"name",lastname:"lastname",age:20};
console.log('break minify optimization');
const {username, lastname, age} = obj;

结果

const obj={username:"name",lastname:"lastname",age:20};console.log("break minify optimization");const{username,lastname,age}=obj;

输入:138字节; 输出:129字节; 压缩率:6.52%, 节省:9字节;

谢谢

如果没有nikk wongMatt的答案,我的解释就不会走那么远,也给他们的答案投票:)

欢迎任何反馈。


-2
投票

我也有同样的疑问。我想破坏会消耗更多内存。通过引用访问对象属性或数组元素时,我们正在访问相同的内存位置。当对象或数组被解构时,如果值是基元,值将被复制到新位置。因此,解构确实比通过对象属性访问消耗更多的内存。

© www.soinside.com 2019 - 2024. All rights reserved.