【问题标题】:Does Passing Ternary Operator as method argument hamper the performance将三元运算符作为方法参数传递是否会影响性能
【发布时间】:2018-12-28 23:19:31
【问题描述】:

以下只是一些示例代码,我相信有很多方法可以重构它,但问题是: 如果代码在下面的循环中以这种方式解释,作为方法参数的三元运算符是否会影响代码性能。

尝试在线搜索,但未收到任何有关性能的信息。

Class employee {

    private int id;  
    private string firstName;  
    private string middleName;  
    private string lastName;  
    private string cellPhone;  
    private string workPhone;  
    private string stNumber;  
    private string stName; 
    private string city;  
    private string state;  
    private string zip;  

    // follow all the getter setter.
}

Class verifyEmployee {

// below loop will throw nullpointer if we don't check null conditions. Provided couple of soultions.New Code 1 and New Code 2.

    ForEach(ListOfOldEmployee oldEmp:ListofOnlyEmployee){
        forEach(ListOfNewEmployee newEmp: ListOfNewEmployee){

            if(firstname based on some condition call verify){
                verify(someobject, oldEmp.getfirstName(),newEmp.getfirstName())
            } else if(middleName based on some condition){
                verify(someobject, oldEmp.getmiddleName(),newEmp.getmiddleName())
            } else if(lastName based on some condition){
                verify(someobject, oldEmp.getlastName(),newEmp.getlastName())
            } else if(cellPhone based on some condition){
                verify(someobject, oldEmp.getcellPhone(),newEmp.getcellPhone())
            } else if(workPhone based on some condition call verify){
                verify(someobject, oldEmp.getworkPhone(),newEmp.getworkPhone())
            } else if(stNumber based on some condition){
                verify(someobject, oldEmp.getstNumber(),newEmp.getstNumber())
            } else if(stName based on some condition){
                verify(someobject, oldEmp.getstName(),newEmp.getstName())
            } else if(city based on some condition){
                verify(someobject, oldEmp.getcity(),newEmp.getcity())
            } else if(state based on some condition){
                verify(someobject, oldEmp.getstate(),newEmp.getstate())
            } else if(zip based on some condition){
                verify(someobject, oldEmp.getzip(),newEmp.getzip())
            }
            ///  --- etc follows
        }
    }

    verify(someobject,string,string){   ---- method I don't send the whole object.
        // process something here here.

    }
}

新代码:1在调用forloop之前检查非空条件

Class verifyEmployee {        

    --------- without ternary oprator use code looks so weird and lengthy.

    string firstNameOldEmp = null;  
    string middleNameOldEmp = null;  
    string lastNameOldEmp = null;  
    string cellPhoneOldEmp = null;  
    string workPhoneOldEmp = null;  
    string stNumberOldEmp = null;  
    string stNameOldEmp = null;  
    string cityOldEmp = null;  
    string stateOldEmp = null;  
    string zipOldEmp = null;  

    string firstNameNewEmp = null;  
    string middleNameNewEmp = null;  
    string lastNameNewEmp = null;  
    string cellPhoneNewEmp = null;  
    string workPhoneNewEmp = null;  
    string stNumberNewEmp = null;  
    string stNameNewEmp = null;  
    string cityNewEmp = null;  
    string stateNewEmp = null;  
    string zipNewEmp = null;  

    if(OldEmp!=null){
        string firstNameOldEmp = oldEmp.getfirstName();
        string middleNameOldEmp = oldEmp.getmiddleName();
        string lastNameOldEmp = oldEmp.getlastName();
        string cellPhoneOldEmp = oldEmp.getcellPhone();
        string workPhoneOldEmp = oldEmp.getworkPhone();
        string stNumberOldEmp = oldEmp.getstNumber();
        string stNameOldEmp = oldEmp.getName();
        string cityOldEmp = oldEmp.getcity();
        string stateOldEmp = oldEmp.getstate();
        string zipOldEmp = oldEmp.getzip();
    }

    if(newEmp!=null){
        string firstNameNewEmp = newEmp.getfirstName();
        string middleNameNewEmp = newEmp.getmiddleName();
        string lastNameNewEmp = newEmp.getlastName();
        string cellPhoneNewEmp = newEmp.getcellPhone();
        string workPhoneNewEmp = newEmp.getworkPhone();
        string stNumberNewEmp = newEmp.getstNumber();
        string stNameNewEmp = newEmp.getName();
        string cityNewEmp = newEmp.getcity();
        string stateNewEmp = newEmp.getstate();
        string zipNewEmp = newEmp.getzip();
    }

    ForEach(ListOfOldEmployee oldEmp:ListofOnlyEmployee){
        forEach(ListOfNewEmployee newEmp: ListOfNewEmployee){

            if(firstname based on some condition call verify){
                verify(someobject, firstNameOldEmp,firstNameNewEmp)
            } else if(middleName based on some condition){
                verify(someobject, middleNameOldEmp,middleNameNewEmp)
            } else if(lastName based on some condition){
                verify(someobject, lastNameOldEmp,lastNameNewEmp)
            } else if(cellPhone based on some condition){
                verify(someobject, cellPhoneOldEmp,cellPhoneNewEmp)
            } else if(workPhone based on some condition call verify){
                verify(someobject, workPhoneOldEmp,workPhoneNewEmp)
            } else if(stNumber based on some condition){
                verify(someobject, stNumberOldEmp,stNumberNewEmp)
            } else if(stName based on some condition){
                verify(someobject, stNameOldEmp,stNameNewEmp)
            } else if(city based on some condition){
                verify(someobject, cityOldEmp,cityNewEmp)
            } else if(state based on some condition){
                verify(someobject, stateOldEmp),stateNewEmp)
            } else if(zip based on some condition){
                verify(someobject, zipOldEmp,zipNewEmp)
            }
            ///  --- etc follows
        }
    }

新代码:2 -- 改用三元运算符

Class verifyEmployee {

--- remove all initlization and use the ternary operator instead. Questions is does this hampper the performance if it's used as method argument
--- and we will be checking not null conditions everytime in the loop of list

    ForEach(ListOfOldEmployee oldEmp:ListofOnlyEmployee){
        forEach(ListOfNewEmployee newEmp: ListOfNewEmployee){

            if(firstname based on some condition call verify){
                verify(someobject, oldEmp!=null?oldEmp.getfirstName():null,newEmp!=null?newEmp.getfirstName():null)
            } else if(middleName based on some condition){
                verify(someobject, oldEmp!=null?oldEmp.getmiddleName():null,newEmp!=null?newEmp.getmiddleName():null)
            } else if(lastName based on some condition){
                verify(someobject, oldEmp!=null?oldEmp.getlastName():null,newEmp!=null?newEmp.getlastName():null)
            } else if(cellPhone based on some condition){
                verify(someobject, oldEmp!=null?oldEmp.getcellPhone():null,newEmp!=null?newEmp.getcellPhone():null)
            } else if(workPhone based on some condition call verify){
                verify(someobject, oldEmp!=null?oldEmp.getworkPhone():null,newEmp!=null?newEmp.getworkPhone():null)
            } else if(stNumber based on some condition){
                verify(someobject, oldEmp!=null?oldEmp.getstNumber():null,newEmp!=null?newEmp.getstNumber():null)
            } else if(stName based on some condition){
                verify(someobject, oldEmp!=null?oldEmp.getstName():null,newEmp!=null?newEmp.getstName():null)
            } else if(city based on some condition){
                verify(someobject, oldEmp!=null?oldEmp.getcity():null,newEmp!=null?newEmp.getcity():null)
            } else if(state based on some condition){
                verify(someobject, oldEmp!=null?oldEmp.getstate():null,newEmp!=null?newEmp.getstate():null)
            } else if(zip based on some condition){
                verify(someobject, oldEmp!=null?oldEmp.getzip():null,newEmp!=null?newEmp.getzip():null)
            }
            ///  --- etc follows
        }
    }
}

【问题讨论】:

  • 现代 JVM 进行优化,无论两者之间有什么区别,这都是荒谬的(几纳秒)。
  • 您应该更关注代码的可读性和可维护性。在显示的代码的这些点上,您确实有改进的空间。
  • 这段代码有点难以理解。编写代码供人类阅读。你证明这段代码是性能瓶颈了吗?如何?我强烈考虑使用chain-of-responsibility pattern 重写它。另见Optional。
  • 另外,您的代码不是 Java - 例如它是 class 而不是 Class。 Java 中的方法和变量在camelCase 中总是,PascalCase 保留用于类名。它是 String 而不是 string。

标签: java ternary-operator


【解决方案1】:

要回答您关于性能的问题,我怀疑是否存在任何实质性差异。您可以在代码前后使用 System.nanoTime() 检查性能,并查看每种方法需要多长时间。但是,请注意 JIT 优化;您应该循环运行代码并查看时间示例。我发现第一个通道很慢,其他通道相当稳定。

正如 cmets 所指出的,第二种解决方案很难阅读。因此,我建议使用第一个。

【讨论】:

  • 这个答案没有任何“我怀疑”的支持 - 我也是,但你有什么证据吗?除了感觉,猜测之外还有什么?此外,使用 microbench Java 的唯一方法是使用 microbench 框架——任何其他建议都是错误的。最后,这只是我的看法,第一个解决方案几乎一样糟糕 - 不推荐使用任何一个选项。
  • 我解释了如何获得“证明”。不,您不需要“微基准框架”来很好地了解方法的执行方式。
  • 你真的这样做了,只使用nanoTime 会给你一个非常混乱的画面——不考虑 GC、JIT、分层编译、类加载、类卸载等等。朴素的基准测试给你朴素的结果,为了改进结果,你添加了预热、迭代、统计技术来确定有用的值。此时,您正在构建一个微基准框架。没有理由不从一开始就使用经过验证的框架。
  • 根据可读性目的,第一个解决方案很好。唯一的问题是代码变得更长。无论如何,我看不到太多代码有人将三元运算符作为方法参数发送,所以一开始有点犹豫。
  • @BoristheSpider:你的 cmets 有点冒犯,没有建设性。此外,这是戈尔什科夫海军上将的一句名言。 “‘更好’是‘足够好’的敌人”在这样一个微不足道的问题上进行过度杀伤性基准测试是不好的做法。
猜你喜欢
  • 2017-03-24
  • 2019-05-30
  • 1970-01-01
  • 2020-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-06
  • 2023-03-21
相关资源
最近更新 更多