hvg*_*des 0 javascript algorithm optimization
我一直在编写一个JS算法.它在铬和狗的速度快,在FF慢.在chrome profiler中,我在一个方法中花费<10%,在FF中,相同的方法是执行时间的30%.有没有javascript结构要避免,因为它们在一个浏览器或其他浏览器中真的很慢?
我注意到的一件事是,如果你做得足够多,像简单的变量声明这样的东西可能会很昂贵.我加快了我的算法,因为他没有这样做
var x = y.x;
dosomthing(x);
Run Code Online (Sandbox Code Playgroud)
而且只是做
dosomething(y.x)
Run Code Online (Sandbox Code Playgroud)
例如.
正如您所发现的,不同的实现中存在不同的问题.根据我的经验,除非做出非常愚蠢的事情,否则在将目标浏览器进行测试时,除非遇到特定的性能问题,否则优化JavaScript代码的速度并不高.通常的"倒数到零"优化(for (i = length - 1; i >= 0; --i)
而不是for (i = 0; i < length; ++i)
)这样的简单事情在实现中甚至都不可靠.因此,我倾向于坚持编写相当清晰的代码(因为我希望对那些必须维护它的人很好,这通常是我),然后担心优化的时间和时间.
也就是说,查看tszming在他/她的回答中链接的Google文章提醒我,在编写代码时,我倾向于记住一些性能问题.这是一个列表(一些来自那篇文章,一些不是):
当你用大量片段构建一个长字符串时,如果你构建一个片段数组然后使用该Array#join
方法创建最终字符串,你通常会获得更好的性能.如果我正在构建一个我将添加到页面的大型HTML代码段,那么我会这么做.
该克罗克福德私人实例变量模式,但冷静和强大的,是昂贵的.我倾向于避免它.
with
昂贵且容易被误解.躲开它.
当然,内存泄漏最终会很昂贵.当您与DOM元素交互时,在浏览器上创建它们相当容易.有关更多详细信息,请参阅文章,但基本上,使用jQuery,Prototype,Closure等良好的库来连接事件处理程序(因为这是一个特别容易出现的区域并且库有帮助),并避免将DOM元素引用存储在其他DOM上元素(直接或间接)通过expando属性.
如果您在浏览器中构建重要的动态内容显示,innerHTML
则在大多数情况下比使用DOM方法(createElement
和appendChild
)更快.这是因为将HTML有效地解析到它们的内部结构中是浏览器所做的事情,并且它们使用优化的编译代码直接写入其内部数据结构,并且非常快速.相反,如果您使用DOM方法构建一个重要的树,那么您将使用一种解释(通常)语言与浏览器交谈,浏览器必须转换为与其内部结构相匹配.我不久前做了一些实验,差异大约是一个数量级(赞成innerHTML
).当然,如果你要建立一个大字符串来分配innerHTML
,请参阅上面的提示 - 最好在数组中构建片段然后使用join
.
缓存已知 - 慢速操作的结果,但不要过度使用,只有在需要时才保留.请记住保留参考的成本与再次查找的成本.
我一再听到人们说从一个包含范围访问变量(当然,全局变量将是最终的例子,但是你可以用其他范围内的闭包来做)比访问本地变速器慢,当然这会使由于定义范围链的方式,在纯粹解释的,非优化的实现中感觉到.但我从未真正看到它在实践中被证明是一个巨大的差异.(链接到简单的快速和脏测试)实际全局变量是特殊的,因为它们是window
对象的属性,它是一个宿主对象,因此与用于其他级别范围的匿名对象略有不同.但我希望你已经避免使用全局变量了.
这是#6的一个例子.几个星期前我在一个与Prototype相关的问题中看到了这个:
for (i = 0; i < $$('.foo').length; ++i) {
if ($$('.foo')[i].hasClass("bar")) { // I forget what this actually was
$$('.foo')[i].setStyle({/* ... */});
}
}
Run Code Online (Sandbox Code Playgroud)
在Prototype中,$$
做一件昂贵的事情:它在DOM树中搜索匹配的元素(在这种情况下,是带有"foo"类的元素).上面的代码在每个循环上搜索DOM 三次:首先检查索引是否在边界内,然后检查元素是否具有类"bar",然后设置样式.
这真是太疯狂了,无论它在哪个浏览器上运行,它都会变得疯狂.您显然希望简要地缓存该查找:
list = $$('.foo');
for (i = 0; i < list.length; ++i) {
if (list[i].hasClass("bar")) { // I forget what this actually was
list[i].setStyle({/* ... */});
}
}
Run Code Online (Sandbox Code Playgroud)
...但是进一步(例如向后工作)是毫无意义的,它可能在一个浏览器上更快而在另一个浏览器上更慢.