Coffeescript 隐式 returns 对性能和副作用的影响
Coffeescript implicit returns impact on performance and side effects
我目前正在使用 Express.js 和 Mongoose 开发 node.js 网络服务。最近,我想尝试一下 CoffeeScript,因为我听说它有一些好处。但是,我发现了一些令人不安的事情,我很好奇是否有人可以澄清一下。
这是我的其中一条路线 javascript:
router.post('/get/:id', decorators.isManager, function(req, res) {
Group.findById(req.params.id, function(err, grp) {
if(err) res.status(500).end();
if(grp == null) res.status(500).send('The group could not be found');
res.send(grp);
});
});
但是,使用以下(几乎等同于 coffeescript):
router.post '/get/:id', decorators.isManager, (req, res) ->
Group.findById req.params.id, (err, grp) ->
res.status(500).end() if err
res.status(500).send 'The group could not be found' if not grp?
res.send grp
将其重新编译为 javascript returns 以下内容:
router.post('/get/:id', decorators.isManager, function(req, res) {
return Group.findById(req.params.id, function(err, grp) {
if(err) res.status(500).end();
if(grp == null) res.status(500).send('The group could not be found');
return res.send(grp);
});
});
那些额外的 returns 会影响我的应用程序的性能吗,它会改变它的工作方式吗?我测试了它,它似乎是相同的响应时间但是我不确定这会对多个嵌套查询产生影响。谢谢!
好问题! this pull request.
中对此进行了广泛讨论
关于性能
请记住,returning undefined
或任何其他值在性能方面几乎是等效的。
但是,所有差异都非常小,因此您不必担心。您可以在这个快速而肮脏的基准测试中比较实际速度变化:http://jsperf.com/return-undefined-vs-value
有一种特殊情况,它可能会造成更大的伤害:当函数中的最后一条语句产生一个数组时。 CoffeeScript 将为您分配数组 return。
例如,在 CoffeeScript 中,您可以这样写:
state = 1
changeState = ->
(state++ for i in [0..9])
将被转译为:
var changeState, state;
state = 1;
changeState = function() {
var i, j, results;
results = [];
for (i = j = 0; j <= 9; i = ++j) {
results.push(state++);
}
return results;
};
但您甚至不想要 results
,您只想添加到 state
!
在这种情况下,最好的选择是添加一个空的 return
语句:
state = 1
changeState = ->
(state++ for i in [0..9])
return
这将导致
var changeState, state;
state = 1;
changeState = function() {
var i, j;
for (i = j = 0; j <= 9; i = ++j) {
state++;
}
};
关于意外后果
CoffeeScript 永远不会改变您代码的行为 - 除非您期望一个函数总是returnundefined
.
不过这并不常见,也不是很有用。如果您想检查 return 值,可能需要一些东西。如果您从未使用过 return 值,那么 return 什么都没有关系。
作为 CoffeeScript 的长期用户,我的观点是您会尽早享受隐式 return。它促使您以更 functional 的方式写作。
我目前正在使用 Express.js 和 Mongoose 开发 node.js 网络服务。最近,我想尝试一下 CoffeeScript,因为我听说它有一些好处。但是,我发现了一些令人不安的事情,我很好奇是否有人可以澄清一下。
这是我的其中一条路线 javascript:
router.post('/get/:id', decorators.isManager, function(req, res) {
Group.findById(req.params.id, function(err, grp) {
if(err) res.status(500).end();
if(grp == null) res.status(500).send('The group could not be found');
res.send(grp);
});
});
但是,使用以下(几乎等同于 coffeescript):
router.post '/get/:id', decorators.isManager, (req, res) ->
Group.findById req.params.id, (err, grp) ->
res.status(500).end() if err
res.status(500).send 'The group could not be found' if not grp?
res.send grp
将其重新编译为 javascript returns 以下内容:
router.post('/get/:id', decorators.isManager, function(req, res) {
return Group.findById(req.params.id, function(err, grp) {
if(err) res.status(500).end();
if(grp == null) res.status(500).send('The group could not be found');
return res.send(grp);
});
});
那些额外的 returns 会影响我的应用程序的性能吗,它会改变它的工作方式吗?我测试了它,它似乎是相同的响应时间但是我不确定这会对多个嵌套查询产生影响。谢谢!
好问题! this pull request.
中对此进行了广泛讨论关于性能
请记住,returning undefined
或任何其他值在性能方面几乎是等效的。
但是,所有差异都非常小,因此您不必担心。您可以在这个快速而肮脏的基准测试中比较实际速度变化:http://jsperf.com/return-undefined-vs-value
有一种特殊情况,它可能会造成更大的伤害:当函数中的最后一条语句产生一个数组时。 CoffeeScript 将为您分配数组 return。
例如,在 CoffeeScript 中,您可以这样写:
state = 1
changeState = ->
(state++ for i in [0..9])
将被转译为:
var changeState, state;
state = 1;
changeState = function() {
var i, j, results;
results = [];
for (i = j = 0; j <= 9; i = ++j) {
results.push(state++);
}
return results;
};
但您甚至不想要 results
,您只想添加到 state
!
在这种情况下,最好的选择是添加一个空的 return
语句:
state = 1
changeState = ->
(state++ for i in [0..9])
return
这将导致
var changeState, state;
state = 1;
changeState = function() {
var i, j;
for (i = j = 0; j <= 9; i = ++j) {
state++;
}
};
关于意外后果
CoffeeScript 永远不会改变您代码的行为 - 除非您期望一个函数总是returnundefined
.
不过这并不常见,也不是很有用。如果您想检查 return 值,可能需要一些东西。如果您从未使用过 return 值,那么 return 什么都没有关系。
作为 CoffeeScript 的长期用户,我的观点是您会尽早享受隐式 return。它促使您以更 functional 的方式写作。