C#和#x27;参考';Javascript中的关键字等效或解决方法
如果我有一个对象:C#和#x27;参考';Javascript中的关键字等效或解决方法,javascript,javascript-objects,Javascript,Javascript Objects,如果我有一个对象: var Edge = function() { this.a = 0; this.b = 0; this.prevEdge = null; this.nextEdge = null; // +20 other members } 和一个函数: function ProcessEdge(e) { // some processing and then e = e.nextEdge; // some processing and then ret
var Edge = function() {
this.a = 0;
this.b = 0;
this.prevEdge = null;
this.nextEdge = null;
// +20 other members
}
和一个函数:
function ProcessEdge(e)
{
// some processing and then
e = e.nextEdge;
// some processing and then return something
}
通过以下方式从其他函数调用:
var e = new Edge();
// some processing and then
var res = ProcessEdge(e);
// e should be now the same object as e.nextEdge
// but it is not, e is still e
e
现在应该是e.nextEdge
,但它仍然是e
,因为e=e.nextEdgeProcessEdge()
函数中的code>中断引用
function main8(a)
{
var pseudo_global_ret = 0;
var res=0, res2, e, b;
for (var i=0;i<10000;i++)
{
e = new Edge();
b = new Edge();
b.a = i*a;
e.nextEdge = b;
_ProcessEdge();
res += pseudo_global_ret;
if (e!=b) res+=1000;
}
return res;
function _ProcessEdge()
{
e = e.nextEdge;
pseudo_global_ret = e.a-10; // instead of return e.a-10
}
}
第一个想法是通过在ProcessEdge()
函数中使用类似e.a=e.nextEdge.a的东西逐个分配每个成员来实现成员平等;e、 b=e.nextEdge.b;e、 prevEdge=e.nextEdge.prevEdge;e、 nextEdge=e.nextEdge.nextEdge代码>,但引用仍处于断开状态。当我这样做的时候,我还必须对每个成员进行比较,然后意大利面代码和它的慢度就出现了
在C#和类似语言中,只需在变量名和引用之前使用ref
关键字,即可实现引用保留,速度、简单性和速度与预期一致
好的,现在是有效的方法(这是我到目前为止使用的方法):
这个方法工作得很好,但问题是内联函数,它(AFAIK)是在每次执行行var res=(function(){}…
时创建的。这个var res…
在循环内部,如果有大量数据,它会被调用很多次,在某些情况下每秒调用100000-500000次
那么,有没有更快的方法来实现参考保留?
编辑:
根据下面的评论,我做了一次速度测试:
结果是,正如我所预料的,上面提到的闭包方法非常慢。我发现最快的方法是删除函数ProcessEdge()
一路走,而不是内联。闭包方法的速度是最快方法速度的26.63%。因此内联方法比闭包方法快3.7倍。内联方法如下:
function main10(a)
{
var res=0, res2, e, b;
for (var i=0;i<10000;i++)
{
e = new Edge();
b = new Edge();
b.a = i*a;
e.nextEdge = b;
// ProcessEdge() as inline version:
e = e.nextEdge;
res += e.a-10;
if (e!=b) res+=1000;
}
return res;
}
还有一种方法值得一提:在函数中使用函数
。它比上述两种方法慢(最快的84.42%),但相当简单。它基本上依赖于与使用全局值
的方法相同的事实:函数可以访问其父作用域变量(对象)以一种不会中断引用的方式,因为没有创建局部变量,函数只处理一个范围内的变量。重要的是,变量没有“传入”,并且没有会中断引用的此类局部赋值
function main8(a)
{
var pseudo_global_ret = 0;
var res=0, res2, e, b;
for (var i=0;i<10000;i++)
{
e = new Edge();
b = new Edge();
b.a = i*a;
e.nextEdge = b;
_ProcessEdge();
res += pseudo_global_ret;
if (e!=b) res+=1000;
}
return res;
function _ProcessEdge()
{
e = e.nextEdge;
pseudo_global_ret = e.a-10; // instead of return e.a-10
}
}
如果尝试某种交换(a,b)
,引用将中断。当然,这对于在闭包内包装以防止全局范围的污染是至关重要的
如果有人找到更快的方法来保留引用,请回答这个问题。否。JavaScript中没有引用调用支持。如图所示,变异对象是可以接受的,并且可以工作,因为。但是,我建议尝试更改代码以使用返回值(可能是复合值)如果可能的话。@pst:您能提供一个您建议的方法(返回复合值)的示例吗?返回{a:1,b:2}
。JavaScript中只能返回一个值,但它可以是复合值/复合值。这比我的(function(){…})快吗?调用(this)
?您必须在特定的环境/代码中运行性能测试。ECMAScript实现性能可能会有很大差异。V8通常在处理类似的对象时非常有效,但对于哪种方法更快/“更好”。
function main8(a)
{
var pseudo_global_ret = 0;
var res=0, res2, e, b;
for (var i=0;i<10000;i++)
{
e = new Edge();
b = new Edge();
b.a = i*a;
e.nextEdge = b;
_ProcessEdge();
res += pseudo_global_ret;
if (e!=b) res+=1000;
}
return res;
function _ProcessEdge()
{
e = e.nextEdge;
pseudo_global_ret = e.a-10; // instead of return e.a-10
}
}
function swap()
{
var tmp=a;
a=b;
b=tmp;
}
var a={x:0}
var b={x:1}
swap();