JavaScriptCore 嵌套“调用”性能问题

Posted

技术标签:

【中文标题】JavaScriptCore 嵌套“调用”性能问题【英文标题】:JavaScriptCore nested "call" performance issue 【发布时间】:2014-12-19 14:40:26 【问题描述】:

如果我定义一个函数

inc = function(x)  return x + 1 

并对其进行嵌套调用

inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(1)))))))))))))))))))))

这将产生值22。如果我修改嵌套表达式以改为使用call,则将null 传递给this,如

inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, 1)))))))))))))))))))))

这也将产生值22

但是,在 javascriptCore 上,第二种形式似乎会消耗 O(2^n) 内存,其中 n 是嵌套调用的数量.如果我在 Firefox 或 Chrome 中尝试此 JavaScript,情况并非如此,因此它似乎与 JavaScriptCore 隔离。

我的 JavaScript 经验很少(几乎没有)。我不知道各种 JavaScript 实现可能做出的权衡,也不知道示例代码在某些实现中是否合理(为闭包提供通用支持等),而在其他实现中高效。

我的问题是:这段代码本身就存在问题吗?是否应该将其重写为以不同的方式构建?还是代码没问题——JavaScriptCore 只是有一个错误?

我做了一些实验,重构一些对临时对象的内部调用将“截断”内存加倍行为

var temp1 = inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, 1)))))));

var temp2 = inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, temp1)))))));

inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, temp2)))))));

【问题讨论】:

我肯定会称之为错误。 谢谢@Pointy。我已经向 Apple 提交了 rdar。 将 rdar 移至 WebKit:bugs.webkit.org/show_bug.cgi?id=139847 这个问题似乎离题了,因为它实际上只是一个错误报告,这篇文章提出的三个问题中有两个主要是基于意见的。 这个问题不是主观的。它是关于特定 JavaScript VM 的行为是否正常。此外,由于 ios 是常见的开发目标,因此其他程序员会想知道这个问题。 【参考方案1】:

基于 cmets 关于这个问题的共识是,编写的代码没有根本问题,但这是 JavaScriptCore 中的一个错误。

对于ticket filed,已确认可重现并已导入苹果的雷达系统。

【讨论】:

只是想知道 inc(x) 通常何时在内部脱糖到 inc.call(window, x) 中。 null 是否必须对此做些什么。 @jsHero 我尝试了一个涉及inc.call(window, inc.call(window, inc.call(window, ... 的测试,它表现出同样的问题。 谢谢迈克。我不明白为什么这个问题已关闭,一些苹果开发人员可能应该回复这个错误的原因。无论如何,这是一个很好的发现@mike。

以上是关于JavaScriptCore 嵌套“调用”性能问题的主要内容,如果未能解决你的问题,请参考以下文章

iOS js oc相互调用(JavaScriptCore)

如何使用 JavaScriptCore 从 Swift 中的 javascript SDK 调用异步 javascript 函数

iOS js oc相互调用JavaScriptCore

iOS js oc相互调用(JavaScriptCore)

swift 笔记:iOS与JavaScript的交互(二):JavaScriptCore:8。调用引入的JavaScript - 调用

swift 笔记:iOS与JavaScript的交互(二):JavaScriptCore:14。 camelCase调用