Javascript 为什么这个代码这么慢? jsc.tools.road.correctType=function(){ 对于(row=jsc.data.selection.startX-1;row

Javascript 为什么这个代码这么慢? jsc.tools.road.correctType=function(){ 对于(row=jsc.data.selection.startX-1;row,javascript,performance,Javascript,Performance,我只能给出一些提示,但不知道它们是否有帮助。没有可能测试您的代码 1-st:在局部函数作用域中声明变量。我是指行和列变量,您将其声明为全局变量(缺少var语句)。访问全局变量比访问局部作用域变量花费更长的时间(AFAIK) jsc.tools.road.correctType = function() { for(row = jsc.data.selection.startX - 1; row <= jsc.data.selection.endX + 1; row++) {

我只能给出一些提示,但不知道它们是否有帮助。没有可能测试您的代码

1-st:在局部函数作用域中声明变量。我是指行和列变量,您将其声明为全局变量(缺少var语句)。访问全局变量比访问局部作用域变量花费更长的时间(AFAIK)

jsc.tools.road.correctType = function() {
    for(row = jsc.data.selection.startX - 1; row <= jsc.data.selection.endX + 1; row++) {
        for(col = jsc.data.selection.startY - 1; col <= jsc.data.selection.endY + 1; col++) {
            if(jsc.data.cells[row-1][col].type != "road" && jsc.data.cells[row+1][col].type != "road" && jsc.data.cells[row][col].type == "road") {
                jsc.ui.addClassToCell("horz", row, col);
            }
            else {
                jsc.ui.removeClassFromCell("horz", row, col);
            }
            if(jsc.data.cells[row][col-1].type != "road" && jsc.data.cells[row][col+1].type != "road" && jsc.data.cells[row][col].type == "road") {
                jsc.ui.addClassToCell("vert", row, col);
            }
            else {
                jsc.ui.removeClassFromCell("vert", row, col);
            }
        }
    }
};

// Elsewhere
jsc.ui.addClassToCell = function(class, x, y) {
    $("#" + x + "-" + y).addClass(class);
};
jsc.ui.removeClassFromCell = function(class, x, y) {
    $("#" + x + "-" + y).removeClass(class);
};
第二:缓存对公共对象的引用。在这里,您可以存储对jsc.data和/ord jsc.data.selection和jsc.data.cells.IIRC的引用,对对象属性的访问是线性的

var row = jsc.data.selection.startX-1;

var col = jsc.data.selection.startY-1;
jsc.tools.road.correctType=function(){
var data=jsc.data,selection=data.selection,cells=jsc.data.cells,ui.jsc.ui;

对于(var row=selection.startX-1,endX=selection.endX+1,endY=selection.endY+1;row,根据选择的大小,您可能需要执行大量的条件检查和DOM编辑


通过注释addClassToCell和removeClassFromCell的内容并比较运行时间,您可以发现条件检查或dom编辑是否花费了最多的时间,从而确定哪一个是最佳的优化对象。

通常,您可以显著优化类似的循环

jsc.tools.road.correctType = function() {
   var data = jsc.data, selection = data.selection, cells = jsc.data.cells, ui.jsc.ui;

   for(var row = selection.startX - 1, endX = selection.endX + 1, endY = selection.endY + 1; row <= endX; ++row) {
      for(var col = selection.startY - 1; col <= endY; ++col) {
         if(cells[row-1][col].type != "road" && cells[row+1][col].type != "road" && cells[row][col].type == "road") {
            ui.addClassToCell("horz", row, col);
         } else {
            ui.removeClassFromCell("horz", row, col);
         }
         if(cells[row][col-1].type != "road" && cells[row][col+1].type != "road" && cells[row][col].type == "road") {
            ui.addClassToCell("vert", row, col);
         } else {
            ui.removeClassFromCell("vert", row, col);
         }
      }
   }
};
虽然它在语义上略有不同,但只要不依赖循环中的顺序(顺序相反),它通常工作得很好

即使您无法更改顺序,也可以通过将someMethod调用移出实际循环来显著改进代码,因为在许多JS实现中,每次迭代都会调用它一次…

使用O()表示法的简短估计:

var x = someMethod();
while( x-- ) {
  //...do stuff
}
$()甚至在嵌套的for中被调用了两次

所以你得到了O(N^4)

您可以通过在jsc.data.cells[row][col]的as属性中缓存计算出的类来对此进行优化,例如

for(row) ... O(N)
for(col) ... O(N)
$().addClass/removeClass ... O(N^2)
并在HTML表中创建单元格时使用缓存数据,而不是为每个单元格调用$()。

使用或本地缓存来存储已创建的jQuery对象。这将减少调用
$
函数的次数

jsc.data.cells[row][col].horz = 1; // don't set class "horz" if not present
jsc.data.cells[row][col].vert = 1;

你能解释一下代码在做什么吗?也许我们可以用更少的代码创建类似的东西。只是有效标记上的一点:元素的ID不应该以数字开头。在它前面加上前缀,例如,不要加“50-32”,“cell_50-32”另外,您有row=selection.startX和col=select.startY。row应该是Y,Column应该是X。正如我确信您已经注意到的,代码文本块和列表不会在标记中组合。语法中存在歧义。咕噜,咕噜,咕噜…确实如此。您只需将代码块缩进至少八个空格字符(四个用于列表,另外四个用于代码块)。“for(var i=0,n=someMethod();ijsc.data.cells[row][col].horz = 1; // don't set class "horz" if not present jsc.data.cells[row][col].vert = 1;
var cache = {}, selector;
for (/* … */) {
    selector = "#" + x + "-" + y;
    if (!cache[selector]) {
        cache[selector] = $(selector);
    }
    // cache[selector] refers to the same object as $("#" + x + "-" + y)
}