简化复杂的if语句

时间:2018-08-15 14:18:25

标签: if-statement optimization coldfusion

我有一个值矩阵需要检查以在页面上显示不同的内容。变量值A和值B分别具有至少3种可能的状态。下面的代码工作正常,但我想知道是否有更好/更聪明的方式来处理此问题。谢谢!

<cfif valueA EQ -1 AND valueB EQ -1>
    <!--- Do something --->
<cfelseif valueA EQ -1 AND valueB EQ 0>
    <!--- Do something --->
<cfelseif valueA EQ -1 AND valueB EQ 1>
    <!--- Do something --->
<cfelseif valueA EQ -1 AND valueB GT 1>
    <!--- Do something --->
<cfelseif valueA EQ 0 AND valueB EQ -1>
    <!--- Do something --->
<cfelseif valueA EQ 0 AND valueB EQ 0>
    <!--- Do something --->
<cfelseif valueA EQ 0 AND valueB EQ 1>
    <!--- Do something --->
<cfelseif valueA EQ 0 AND valueB GT 1>
    <!--- Do something --->
<cfelseif valueA EQ 1 AND valueB EQ -1>
    <!--- Do something --->
<cfelseif valueA EQ 1 AND valueB EQ 0>
    <!--- Do something --->
<cfelseif valueA EQ 1 AND valueB EQ 1>
    <!--- Do something --->
<cfelseif valueA EQ 1 AND valueB GT 1>
    <!--- Do something --->
<cfelseif valueA GT 1 AND valueB EQ -1>
    <!--- Do something --->
<cfelseif valueA GT 1 AND valueB EQ 0>
    <!--- Do something --->
<cfelseif valueA GT 1 AND valueB EQ 1>
    <!--- Do something --->
<cfelseif valueA GT 1 AND valueB GT 1>
    <!--- Do something --->
</cfif> 

2 个答案:

答案 0 :(得分:4)

ColdFusion引擎不会在上面的代码中看到复杂性。人类开发人员会遇到一些困难(尽管我确定有些人可以毫无问题地解析它(不是我))。

这是我的版本,至少通过我自己可以使用编辑器的代码折叠功能,使其更易于阅读。

<cfif valueA EQ -1>

    <cfif valueB EQ -1>
        <!--- Do something --->
    <cfelseif valueB EQ 0>
        <!--- Do something --->
    <cfelseif valueB EQ 1>
        <!--- Do something --->
    <cfelseif valueB GT 1>
        <!--- Do something --->
    </cfif>    

<cfelseif valueA EQ 0>

    <cfif valueB EQ -1>
        <!--- Do something --->
    <cfelseif valueB EQ 0>
        <!--- Do something --->
    <cfelseif valueB EQ 1>
        <!--- Do something --->
    <cfelseif valueB GT 1>
        <!--- Do something --->
    </cfif> 

<cfelseif valueA EQ 1>

    <cfif valueB EQ -1>
        <!--- Do something --->
    <cfelseif valueB EQ 0>
        <!--- Do something --->
    <cfelseif valueB EQ 1>
        <!--- Do something --->
    <cfelseif valueB GT 1>
        <!--- Do something --->
    </cfif> 

<cfelseif valueA GT 1>

    <cfif valueB EQ -1>
        <!--- Do something --->
    <cfelseif valueB EQ 0>
        <!--- Do something --->
    <cfelseif valueB EQ 1>
        <!--- Do something --->
    <cfelseif valueB GT 1>
        <!--- Do something --->
    </cfif> 

</cfif>


希望对您有所帮助。

答案 1 :(得分:1)

为了向您展示不同选项的行为方式,我用到目前为止提出的2个cfif选项创建了一个小提琴,并添加了一个带有一点数学魔术的switch选项以进行切换工作。

整个小提琴位于:https://trycf.com/gist/041d1a6c3b3701d30306a9c80f1ddbea/acf2018?theme=monokai

我的switch代码:

local.valA = arguments.valueA>1?99:arguments.valueA ; // If GT 1, then 99
local.valB = arguments.valueB>1?99:arguments.valueB ; // If GT 1, then 99

local.finalOut = "" ;

switch (valA*valB) { // multiply the two vals and it will be -1,0,1,99,-99 or -99*99
    case -1 : // One is -1 and One is 1 >> 1*-1=-1
        if (valA == 1) {
            finalOut = "1,-1" ;   
        } else {
            finalOut = "-1,1" ;
        }
        break ;
    case 1 : // Both are either 1 or -1  >> -1*-1=1 | 1*1=1
        if (valA == 1) {
            finalOut = "1,1" ;   
        } else {
            finalOut = "-1,-1" ;
        }
        break ;
    case 0 : // One is 0  >> 0*x=0
        if (valA == 0) {
            switch (valB) {
                case -1 : 
                    finalOut = "0,-1" ;
                    break;
                case 0 : 
                    finalOut = "0,0" ;
                    break;
                case 1 : 
                    finalOut = "0,1" ;
                    break;
                case 99 : 
                    finalOut = "0,99" ;
                    break;
            }
        } else {
            switch (valA) {
                case -1 : 
                    finalOut = "-1,0" ;
                    break;
                case 1 : 
                    finalOut = "1,0" ;
                    break;
                case 99 : 
                    finalOut = "99,0" ;
                    break;
            }
        }
        break ;
    default : // One > 1, Other not 0
        switch (ValA) {
            case -1 : // ValA is -1, ValB is >1
                finalOut = "-1,99" ;
                break ;
            case 1 : // ValA is 1, ValB is >1
               finalOut = "1,99" ;
                break ;
            case 99 : // ValA is >1, ValB <> 0
                switch (valB) {
                    case 1 :
                        finalOut = "99,1" ;
                        break ;
                    case -1 :
                        finalOut = "99,-1" ;
                        break ;
                    case 99 :
                        finalOut = "99,99" ;
                        break;
                }
                break ;
        }
        break ;
}

“我的小提琴”将3个选项中的每个选项都放到一个函数中,因此我可以多次遍历它们以演示它们并检查计时。有关这些功能,请参见上面的小提琴。

一些注意事项:就性能而言,您绝对想尽量使逻辑短路。我的switch和Alex的cfif解决方案都比原始的未嵌套cfif快一点。这证明了嵌套选项以绕过某些逻辑的价值。

cfif从上到下工作。当我更改数组以添加约10万行并且主要包含无需在循环过程中经过很多选择即可满足条件的值时,这三个选项的执行情况都非常相似。如果我包含的条件会落在选项的末尾,那么原始的cfif的性能要比其他两个使逻辑短路的选项cfif和{{1 }}的表现非常相似。

我测试了大约1M,100K和10K的行。行数较少时,所有3项的性能都非常接近。我认为这可能是因为变量实例化和数学检查相当一致(尽管有迭代次数),并且在switch版本中不需要。

我没有测试的一件事是标签与脚本。我用脚本语法写了cfif,而在标签语法中可能会更快。我也没有测试脚本中的switch中的任何一个。这可能会有所不同。绕开逻辑也可能会改变选项的速度。

TL; DR::由于我相信您说过,您将使用该方法仅评估一组值,因此Alex的解决方案可能效果最好。我认为您应该选择最容易阅读和解释的内容。我的例子主要是因为您询问性能。 :-)