在 javascript class 构造函数内声明变量与在所述构造函数内调用的方法是否存在有意义的性能差异?
Are there meaningful performance differences for declaring variables inside javascript class constructor vs a method called inside said constructor?
我是 JS 和 Whosebug 的新手,但对编码并不陌生,所以请原谅我,如果这已经在某处得到解答。
采用第二种方式的原因只是为了改进 class 的 'neatness'。我想知道这样做是否会对可读性进行性能权衡。
更清楚:
这样做是否有性能损失:
class MyClass{
constructor(args){
this.UpdateClass(args);
}
UpdateClass(args){
this.firstVar = this.GetFirstVar();
this.secondVar = this.GetSecondVar(args);
}
GetFirstVar(){
return 420;
}
GetSecondVar(args){
return args.Cheesesteak;
}
}
而不是这样做:
class MyClass{
constructor(args){
this.firstVar = this.GetFirstVar();
this.secondVar = this.GetSecondVar(args);
}
UpdateClass(args){
this.firstVar = this.GetFirstVar();
this.secondVar = this.GetSecondVar(args);
}
GetFirstVar(){
return 420;
}
GetSecondVar(args){
return args.Cheesesteak;
}
}
我对阅读 Google 的 js 风格指南的解释是,他们应该始终在构造函数中声明 class 变量,因为在另一个方法中声明 class 变量的计算成本更高,但是当 class 方法定义 and/or 无一例外地更新每个 class 变量时,情况仍然如此吗?
好的,感谢@Bergi 和@VLAZ 在这方面的帮助。我最终在 jsfiddle 中测试了这个代码片段:
class MyClass {
constructor(data) {
this.UpdateClass(data);
}
UpdateClass(data) {
this.firstVar = this.GetFirstVar(data);
this.secondVar = this.GetSecondVar(data);
}
GetFirstVar(data) {
var first = data.slice(1, 4).join();
return first;
}
GetSecondVar(data) {
var cat = data.slice(2, 5);
return cat;
}
}
class MyClass2 {
constructor(data) {
this.firstVar = this.GetFirstVar(data);
this.secondVar = this.GetSecondVar(data);
}
UpdateClass(data) {
this.firstVar = this.GetFirstVar(data);
this.secondVar = this.GetSecondVar(data);
}
GetFirstVar(data) {
var first = data.slice(1, 4).join();
return first;
}
GetSecondVar(data) {
var cat = data.slice(2, 5);
return cat;
}
}
var testData = ['AB', 'AB', 'AB', 'AB', 'AB', 'AB', 'AB'];
var case1= 0;
var case2= 0;
var caseup=0;
for(let y = 0; y < 10; y++){
var start = new Date().getTime();
for (let i = 0; i < 300000; i++) {
var testClass = new MyClass(testData);
}
var stop = new Date().getTime();
case1 += stop - start;
start = new Date().getTime();
for (let i = 0; i < 300000; i++) {
var testClass = new MyClass2(testData);
}
stop = new Date().getTime();
case2 += stop - start;
var testClass = new MyClass(testData);
start = new Date().getTime();
for (let i = 0; i < 300000; i++) {
testClass.UpdateClass(testData);
}
stop = new Date().getTime();
caseup += stop - start;
}
console.log(`Difference in first case is: ${case1 / 10} ms`)
console.log(`Difference in second case is: ${case2 / 10} ms`)
console.log(`Difference in update case is: ${caseup / 10} ms`)
Output (3m iterations):
Difference in first case is: 493.4 ms
Difference in second case is: 500.3 ms
Difference in update case is: 469.9 ms
所以在这个简化版本中,实例化 class 数百万次时确实存在性能差异,但是对于数量级较低的值,性能差异变得不那么明显:
Output (300k iterations):
Difference in first case is: 49.6 ms
Difference in second case is: 49.1 ms
Difference in update case is: 47 ms
编辑:我添加了简单的更新案例并将测试重写为 运行 十次并取平均值。结果应该更可靠。
我是 JS 和 Whosebug 的新手,但对编码并不陌生,所以请原谅我,如果这已经在某处得到解答。
采用第二种方式的原因只是为了改进 class 的 'neatness'。我想知道这样做是否会对可读性进行性能权衡。
更清楚:
这样做是否有性能损失:
class MyClass{
constructor(args){
this.UpdateClass(args);
}
UpdateClass(args){
this.firstVar = this.GetFirstVar();
this.secondVar = this.GetSecondVar(args);
}
GetFirstVar(){
return 420;
}
GetSecondVar(args){
return args.Cheesesteak;
}
}
而不是这样做:
class MyClass{
constructor(args){
this.firstVar = this.GetFirstVar();
this.secondVar = this.GetSecondVar(args);
}
UpdateClass(args){
this.firstVar = this.GetFirstVar();
this.secondVar = this.GetSecondVar(args);
}
GetFirstVar(){
return 420;
}
GetSecondVar(args){
return args.Cheesesteak;
}
}
我对阅读 Google 的 js 风格指南的解释是,他们应该始终在构造函数中声明 class 变量,因为在另一个方法中声明 class 变量的计算成本更高,但是当 class 方法定义 and/or 无一例外地更新每个 class 变量时,情况仍然如此吗?
好的,感谢@Bergi 和@VLAZ 在这方面的帮助。我最终在 jsfiddle 中测试了这个代码片段:
class MyClass {
constructor(data) {
this.UpdateClass(data);
}
UpdateClass(data) {
this.firstVar = this.GetFirstVar(data);
this.secondVar = this.GetSecondVar(data);
}
GetFirstVar(data) {
var first = data.slice(1, 4).join();
return first;
}
GetSecondVar(data) {
var cat = data.slice(2, 5);
return cat;
}
}
class MyClass2 {
constructor(data) {
this.firstVar = this.GetFirstVar(data);
this.secondVar = this.GetSecondVar(data);
}
UpdateClass(data) {
this.firstVar = this.GetFirstVar(data);
this.secondVar = this.GetSecondVar(data);
}
GetFirstVar(data) {
var first = data.slice(1, 4).join();
return first;
}
GetSecondVar(data) {
var cat = data.slice(2, 5);
return cat;
}
}
var testData = ['AB', 'AB', 'AB', 'AB', 'AB', 'AB', 'AB'];
var case1= 0;
var case2= 0;
var caseup=0;
for(let y = 0; y < 10; y++){
var start = new Date().getTime();
for (let i = 0; i < 300000; i++) {
var testClass = new MyClass(testData);
}
var stop = new Date().getTime();
case1 += stop - start;
start = new Date().getTime();
for (let i = 0; i < 300000; i++) {
var testClass = new MyClass2(testData);
}
stop = new Date().getTime();
case2 += stop - start;
var testClass = new MyClass(testData);
start = new Date().getTime();
for (let i = 0; i < 300000; i++) {
testClass.UpdateClass(testData);
}
stop = new Date().getTime();
caseup += stop - start;
}
console.log(`Difference in first case is: ${case1 / 10} ms`)
console.log(`Difference in second case is: ${case2 / 10} ms`)
console.log(`Difference in update case is: ${caseup / 10} ms`)
Output (3m iterations):
Difference in first case is: 493.4 ms
Difference in second case is: 500.3 ms
Difference in update case is: 469.9 ms
所以在这个简化版本中,实例化 class 数百万次时确实存在性能差异,但是对于数量级较低的值,性能差异变得不那么明显:
Output (300k iterations):
Difference in first case is: 49.6 ms
Difference in second case is: 49.1 ms
Difference in update case is: 47 ms
编辑:我添加了简单的更新案例并将测试重写为 运行 十次并取平均值。结果应该更可靠。