是否可以动态重写您的JavaScript

时间:2013-04-30 01:22:33

标签: javascript dynamic if-statement

我想动态地在javascript中编辑我的if else语句。

因此,在使用一个if语句后,可以将其删除。我觉得这可能是不可能的,但在网上搜索失败后,我的好奇心请求我问。

例如:

if (x > 200 && x % 25 === 0) {
  doSomething1();
} else if (x > 300 && !inRange) {
  doSomething2();
} else if (x > 400 && x % 7 === 0) {
  doSomething3();
}

此循环中有八个if else语句。循环确定要创建的对象。在几分钟内创建了2000个对象。如果我们平均在破裂之前达到第四个陈述,那么在这一组陈述中就会执行8,000个计算。

我想简化脚本的速度和再次,好奇如果我们可以实际编写javascript而不使用单独的函数等。在if语句失败后,通常不再需要它。我想下一个声明,包括动态删除其前任的代码。这可能会节省3到4千个计算 - 我知道这个计算并不是很大,但考虑到还有很多其他的事情发生,这值得考虑。

有没有办法动态删除它们,或者是否有人有任何技巧或模式?

另外,即使这在js中不可用,这会被称为什么?

6 个答案:

答案 0 :(得分:2)

为什么要动态删除它们?动态地改变代码是不必要的,并且一堆蠕虫在这种情况下过度使用它。你应该使用旗帜。

我会单独回答你是否试图跳过一大堆if语句或if if语句。

前言

正如您对问题的评论中所述,请运行profiling以确保您知道性能问题在哪里!

你提到你厌恶简单地使用布尔标志来使你的答案中没有运行if语句。这很好,这是人们通常做的事情。这不应该是一个实际的性能问题,并且分析可能会显示您的性能问题在其他地方。如果他们不这样做,并且这个布尔标志检查确实是你的瓶颈 - 你有更大的问题,比如期望从JavaScript代码中过多,或者你没有正确使用分析工具,或者误解了它的结果。

如果你试图避免运行if语句的主体或它的条件,那么这些对你来说比boolean flag检查本身更重要。

用于跳过大量if语句

在条件中包装你的一堆 if 语句。

if (runBunchOfIfStatements) {
    // all those if statements here
}

如果你想要运行那些if语句,那么将runBunchOfIfStatements标志设置为false(当然,你应该选择一个更有意义的名称)。

那就是说,8或9 if语句是代码长度问题,并且很可能对性能问题毫无意义 - 除非那些if语句恰好涉及非常密集的检查。如果你担心只是,因为有很多如果检查,你可能会找错了地方。

对于个人if语句

假设您只有一个 if语句要跳过。你的答案中有这个代码:

} else if (x > 300 && !doneSomething2) {
  doSomething2();
  doneSomething2 = 1;
}

这很好。你只是做了一个小小的检查:见前言。在其他地方寻找您的性能问题。可以稍微改写一下,以便更加严格地遵循惯例(我即将达成),但在这种情况下,这种变化将产生微不足道的影响。

我们假设 实际上是一个性能问题。假设您没有检查x > 300,而是像calculateSeveralSquareRoots()那样更加密集。通常,你采取这种方法,但你重新排列它:

} else if (needCalculations && calculateSeveralSquareRoots() {
    // do stuff
    needCalculations = false;
}

这里的区别是 needCalculations标志首先出现,而不是第二个。 JavaScript的比较运算符有short circuit evaluation。这意味着在评估a && b时,如果a为false,b甚至不会被检查 - 我们已经知道结果将为false。如果该标志首先出现,则意味着calculateSeveralSquareRoots()永远不会运行,并且您可以节省检查时间。

如果旗帜排在第二位,那么你可能会浪费很多时间在这个函数上,因为这个条件几乎总是可以解决为false,这要归功于那个旗帜。

所以在你的原文中,你可以在 x > 300评估之前得到标志,只是为了遵循惯例。但是再次...... 如果像这样的if语句对你来说是一个真正重要的性能问题,那么你就会遇到更大的问题。

答案 1 :(得分:2)

没有。而对此的需求将表明设计不佳。

如您所述,您应该使用条件表达式来确定应该运行哪个代码段。如果在代码中传递了某个阈值,之后不再需要在循环中执行条件,为什么不简单地break循环并使用新的代码块来处理doSomethingElse子句。如果您使用的是setInterval,那么您可以调用clearInterval,然后在必要时触发一些新操作。无论如何,运行单个(甚至几个)简单条件语句不会增加太多开销,并且无论如何都不太可能成为优化的限制因素。

答案 2 :(得分:2)

忽略这一事实,我怀疑这是现代浏览器的一个瓶颈JIT JavaScript(CPU非常擅长预测分支)如图所示,因为简单的数字比较即使在具有智能预测的大型迭代中也不会很昂贵编译。

您可以通过注入不同的功能来执行此操作:

checker: function(x) {
    if (x > 200) {
        doSomething1();
    }
    else if (x > 300) {
        doSomething2();
    }
    else if (y > 400) {
        doSomething3();
    }
}

可以更改为

checker: function(x) {
    if (x > 200) {
        doSomething1();
    }
    else if (x > 300) {
        doSomething2();
        this.checker = smallerChecker;
    }
    else if (y > 400) {
        doSomething3();
    }
}

function smallerChecker(x) {
    if (x > 200) {
        doSomething1();
    }
    else if (y > 400) {
        doSomething3();
    }
}

从根本上说,您只需要将行为注入,然后根据您认为合适的方式进行更改。通过像上面那样替换完成检查的功能(功能方式),或者让对象替换它(OO方式)。

答案 3 :(得分:1)

按可能性顺序对它们进行排序(因此,如果> 400是最常见的,请首先检查,如果x <200是下一个最常见的,请检查,等等。)示例代码按增加的顺序排列

接下来,你的代码没有显示它,你只是暗示它,这是一个循环。 (如果它不是一个循环,那么这不是一个感兴趣的性能问题)你可以尝试像Duff设备这样的花哨循环。

并确定可以更改哪些代码以使用更多本机API会产生神奇的差异,而像这样的代码优化可能只会产生微不足道的差异。

答案 4 :(得分:0)

如果您希望它是动态的,您可以随时拥有一系列与操作相关的条件,并且一旦执行,这些条件就会从集合中删除。但是,我怀疑这会导致更快的代码执行,但您必须创建一个jsperf测试才能确定。

DEMO:http://jsfiddle.net/a2ZEj/1/

function doSomethingA() {}
function doSomethingB() {}

var doOperation = (function doOperation() {
    var operations = [
        {
            check: function (someArg) {
                return someArg > 100;
            },
            exec: doSomethingA
        },
        {
            check: function (someArg) {
                return someArg > 100 && someArg < 200;
            },
            exec: doSomethingB
        }
    ];

    return function (someArg) {
        var i = 0,
            len = operations.length,
            item;

        for (; i < len; i++) {
            if ((item = operations[i]).check(someArg)) {
                item.exec();
                operations.splice(i, 1);
                console.log('executed ' + item.exec.name);
                return;
            }
        }
    };
})();

doOperation(101); //calls doSomethingA
doOperation(101); //calls doSomethingB
doOperation(101); //does nothing

答案 5 :(得分:0)

您可以创建如下方法并创建动态条件

function buildCond(lhv1,rhv1,lhv2,rhv2) 
{
    var condition1,condition2;
    condition1 = condition2 = '';
    if(rhv1 !== -1){
        condition1 =  lhv1 + " == " + rhv1 + " && ";
    } 
    if(rhv2 !== -1){
        condition2 =  lhv2 + " == " + rhv2 + " && ";
    }
    return condition1 + condition2;
}

And then call this method with eval to execute

if(eval(buildCond(var1,value1,var2,value2)) === true){
    //do stuff
}