锁定老帖子 主题:实践中的重构06_方法调用顺序和性能
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-11-15
最后修改:2011-02-26
public boolean f_0(String userId) { // isLoginAgainInMonth is local call. boolean isLoginAgainInMonth = isLoginAgainInMonth(userId); // isGardUser is ws call. boolean isGardUser = isGardUser(userId); return isLoginAgainInMonth || isGardUser; } 上面的code判断了一个用户是本月的非第一次登录,或者是一个受保护的用户,是的话返回true,做一些处理。 大眼一看,这段代码当然是没有什么问题的。但是加上性能的考量,问题就出来了。 isLoginAgainInMonth是一个local call,isGardUser是一个ws call,当isLoginAgainInMonth为true的时候是可以直接返回的,多调用一次isGardUser就多一次ws开销,这个开销包括网络开销,内存开销,甚至db开销。如果该代码被大量执行次数放大的话,所消耗的资源还是很可观的。 这里调整代码来强调方法的调用顺序对性能的影响。重构后为: /** * Note: 为了性能考量,先调用本地方法,后调用ws服务,当可以判断出结果的时候,尽早返回。 * */ public boolean f_1(String userId) { // isLoginAgainInMonth is local call. if (isLoginAgainInMonth(userId)) { return true; } // isGardUser is ws call. return isGardUser(userId); } 还有一种利用短路特性的写法。 /** * 不推荐的写法。 * */ public boolean f_2(String userId) { return isLoginAgainInMonth(userId) || isGardUser(userId); } 这种写法利用短路的特性达到了同样的功能,并且看上去代码更简洁。 但是,应该承认的是,并不是所有程序员对短路的特性都掌握了,同时,即使掌握短路的程序员看到这段代码的时候也未必能够意识到这里的短路和性能相关。该写法没有达到强调方法调用顺序和性能的关系的作用,因此不推荐这种写法。 谢谢tuti的建议。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-11-15
最后修改:2010-11-15
zhang_xzhi_xjtu 写道 //isLastLoing is local call. boolean isLoginAgainInMonth=isLoginAgainInMonth(userId); if(isLoginAgainInMonth){ return true; } //isGardUser is ws call. boolean isGardUser=isGardUser(userId); return isGardUser; 这样如何? return isLoginAgainInMonth(userId)||isGardUser(userId); |
|
返回顶楼 | |
发表时间:2010-11-15
tuti 写道 zhang_xzhi_xjtu 写道 //isLastLoing is local call. boolean isLoginAgainInMonth=isLoginAgainInMonth(userId); if(isLoginAgainInMonth){ return true; } //isGardUser is ws call. boolean isGardUser=isGardUser(userId); return isGardUser; 这样如何? return isLoginAgainInMonth(userId)||isGardUser(userId); 这个当然也行,最早我也是这个想法,但是考虑到未必所有的人都知道短路,才用长一点的方式写,这样可以突出早返回这个特性,后来的程序员也就不会忽略这个东西了。 |
|
返回顶楼 | |
发表时间:2010-11-15
zhang_xzhi_xjtu 写道 tuti 写道 zhang_xzhi_xjtu 写道 //isLastLoing is local call. boolean isLoginAgainInMonth=isLoginAgainInMonth(userId); if(isLoginAgainInMonth){ return true; } //isGardUser is ws call. boolean isGardUser=isGardUser(userId); return isGardUser; 这样如何? return isLoginAgainInMonth(userId)||isGardUser(userId); 这个当然也行,最早我也是这个想法,但是考虑到未必所有的人都知道短路,才用长一点的方式写,这样可以突出早返回这个特性,后来的程序员也就不会忽略这个东西了。 这样如何? if(is_login_again_in_month(userId)){ return true; } return is_gard_user_via_call_ws(userId); |
|
返回顶楼 | |
发表时间:2010-11-15
最后修改:2010-11-15
tuti 写道 zhang_xzhi_xjtu 写道 tuti 写道 zhang_xzhi_xjtu 写道 //isLastLoing is local call. boolean isLoginAgainInMonth=isLoginAgainInMonth(userId); if(isLoginAgainInMonth){ return true; } //isGardUser is ws call. boolean isGardUser=isGardUser(userId); return isGardUser; 这样如何? return isLoginAgainInMonth(userId)||isGardUser(userId); 这个当然也行,最早我也是这个想法,但是考虑到未必所有的人都知道短路,才用长一点的方式写,这样可以突出早返回这个特性,后来的程序员也就不会忽略这个东西了。 这样如何? if(is_login_again_in_month(userId)){ return true; } return is_gard_user_via_call_ws(userId); 这个也考虑过,只是为了方便调试,一般把方法的返回值都独立出来。 |
|
返回顶楼 | |
发表时间:2010-11-15
zhang_xzhi_xjtu 写道 这个也考虑过,只是为了方便调试,一般把方法的返回值都独立出来。 方便在哪? |
|
返回顶楼 | |
发表时间:2010-11-16
gdpglc 写道 zhang_xzhi_xjtu 写道 这个也考虑过,只是为了方便调试,一般把方法的返回值都独立出来。 方便在哪? 以后还要加判断什么地,多加几个你就知道这么写会改起来容易 |
|
返回顶楼 | |
发表时间:2010-11-16
我觉得短路多好,简单易懂,那两个变量看着就不舒服。
|
|
返回顶楼 | |
发表时间:2010-11-16
最后修改:2010-11-16
seele 写道 gdpglc 写道 zhang_xzhi_xjtu 写道 这个也考虑过,只是为了方便调试,一般把方法的返回值都独立出来。 方便在哪? 以后还要加判断什么地,多加几个你就知道这么写会改起来容易 以后等需要再变.... 尽量不过度设计..... PS:你的设计像是在说拷贝很方便,来用拷贝方式吧. 我的项目有有很多这样的提前预判过期的东西. 我用一个cache类(后来是包)放. 刚刚改成定时抓取的,(需求....) |
|
返回顶楼 | |
发表时间:2010-11-16
这个也考虑过,只是为了方便调试,一般把方法的返回值都独立出来。 我也想知道到底方便在哪里? 楼主的上一个帖子,不是也直接这样了吗? 实践中的重构05_简洁的代码 if (a|| b|| c) { return true; } return false; 可以改为 return a|| b|| c; |
|
返回顶楼 | |