性能-Java方法调用与使用变量

最近,我与团队负责人就使用临时变量与调用getter方法进行了讨论。 很长时间以来,我一直认为,如果我必须多次调用一个简单的getter方法,我会将其放入一个temp变量中,然后使用该变量。 我认为这在样式和性能上都会更好。 但是,我的负责人指出,在Java 4和更高版本中,这有些不正确。 他坚信使用较小的变量空间,因此他告诉我,与使用temp变量相比,调用getter方法对性能的影响很小,因此使用getters更好。 但是,我并不完全相信他的说法。 你们有什么感想?

Seagull asked 2020-06-20T05:40:11Z

14个解决方案

70 votes

永远不要为提高性能而编写代码,而总是为了提高可读性而编写代码。 让编译器完成工作。

他们可以改善编译器/运行时,以便更快地运行良好的代码,突然之间,“快速”代码实际上在减慢系统速度。

Java编译器和运行时优化似乎首先解决了更常见/可读的代码,因此,与刚刚编写的代码相比,您的“ Optimized”代码在以后的时间更有可能被取消优化。

注意:

这个答案是指Java代码“技巧”,就像所提到的问题一样,不是很糟糕的编程,它可能会提高从O(N)到O(N ^ 2)的循环级别。 通常,编写干净的DRY代码,然后等待操作花费很长时间才能修复它。 除非您是游戏设计师,否则您几乎永远不会达到这一点。

Bill K answered 2020-06-20T05:40:39Z

24 votes

您的线索是正确的。 在现代版本的VM中,内联了返回私有字段的简单getter,这意味着不存在方法调用的性能开销。

Randolpho answered 2020-06-20T05:40:59Z

14 votes

不要忘记通过将getSomething()的值分配给变量而不是两次调用它,您假设getSomething()在第二次调用它时将返回相同的东西。 在您所讨论的场景中,也许这是一个正确的假设,但有时并非如此。

Paul Clapham answered 2020-06-20T05:41:20Z

11 votes

这取决于。 如果您想清楚地说明您一次又一次使用相同的值,则可以将其分配给temp变量。 如果getter的调用有点长,例如myCustomObject.getASpecificValue(),我会这样做。

如果可读性强,您将在代码中得到更少的错误。 所以这是重点。

性能差异很小或根本不存在。

tangens answered 2020-06-20T05:41:49Z

8 votes

如果您牢记代码的演变,则v1.0中的简单getter往往在v2.0中变得不那么简单。

将简单的getter更改为不太简单的getter的编码人员通常不知道有一个函数会调用此getter 10次而不是1次,并且永远不会在那里进行更正,依此类推。

这就是为什么从DRY主体的角度来看,缓存值以供重复使用是有意义的。

Alexander Pogrebnyak answered 2020-06-20T05:42:18Z

6 votes

我不会将“代码可读性”牺牲到几微秒。

吸气器性能更好,可以在运行时中节省几微秒的时间,这也许是事实。 但是我相信,当错误修复时间到来时,变量可以为您节省几个小时甚至几天。

很抱歉提供非技术性答案。

Hendra Jaya answered 2020-06-20T05:42:47Z

2 votes

我认为,如果满足某些条件,JVM的最新版本通常足够聪明,可以自动缓存函数调用的结果。 我认为该函数必须没有副作用,并且每次调用都可靠地返回相同的结果。 请注意,对于简单的getter来说,可能会或可能不会,取决于类中其他代码对字段值所做的操作。

如果不是这种情况,并且被调用的函数进行了大量处理,那么将其结果缓存在临时变量中确实会更好。 尽管呼叫的开销微不足道,但是如果您呼叫午餐的次数过多,那么繁忙的方法就会吃掉您的午餐。

我也会练习你的风格; 即使不是出于性能原因,当我的代码中没有很多函数调用时,我也会觉得代码更清晰。

Carl Smotricz answered 2020-06-20T05:43:16Z

1 votes

如果仅仅是getFoo(),这是不值得的。通过将其缓存到temp变量中,您并没有使其变得更快,并且可能自找麻烦,因为getFoo()以后可能会返回不同的值。 但是,如果它类似于getFoo().getBar().getBaz().getSomething(),并且您知道该值不会在代码块内更改,则可能有理由使用temp变量以提高可读性。

fastcodejava answered 2020-06-20T05:43:37Z

0 votes

一般评论:在任何现代系统中,除I / O之外,都不必担心性能问题。 快速的CPU和大量的内存意味着所有其他问题在大多数时候对系统的实际性能完全不重要。 [当然,也有诸如缓存解决方案之类的例外,但是它们很少而且很少见。]

现在要解决这个特定问题,是的,编译器将内联所有获取。 但是,即使这不是实际的考虑因素,真正重要的还是整个代码的可读性和流程。 如果使用多次调用(例如customer.gerOrder()。getAddress())更好地捕获在局部变量中,则用局部变量代替间接调用会更好。

user234054 answered 2020-06-20T05:44:03Z

0 votes

与之后声明的任何局部变量相比,虚拟机可以更有效地处理前四个局部变量(请参见lload和lload_ 指令)。 因此,缓存(内联)getter的结果实际上可能会损害您的性能。

当然,它们对性能的影响几乎可以忽略不计,因此,如果要优化代码,请确保确实解决了实际的瓶颈!

Bombe answered 2020-06-20T05:44:28Z

0 votes

不使用临时变量来包含方法调用结果的另一个原因是,使用该方法可以获得最新的值。 实际的代码可能不会有问题,但是更改代码后可能会成为问题。

kiamlaluno answered 2020-06-20T05:44:49Z

0 votes

如果您确定getter将在整个范围内返回相同的值,则我建议使用temp变量。 因为如果您的变量名称的长度为10或更大,则getter在可读性方面看起来很糟糕。

Rishikesh Chaudhari answered 2020-06-20T05:45:09Z

0 votes

我已经用非常简单的代码对其进行了测试:

用int的简单getter创建了一个类(我用Num的final和non-final值进行了尝试,没有发现任何区别,请注意,在这种情况下,num永远也不会改变...!):

1: for(int i = 0; i < num.getNumber(); ++i){(...)}

2: number = num.getNumber();

for(int i = 0; i < number; ++i){(...)}

比较2个不同的for循环:

1: for(int i = 0; i < num.getNumber(); ++i){(...)}

2: number = num.getNumber();

for(int i = 0; i < number; ++i){(...)}

结果大约是第一个3毫秒,第二个大约2毫秒。 因此,两者之间存在微小差异,对于小循环,无需担心,在大迭代中或者如果您始终调用getter并非常需要它们,可能会遇到更多问题。 例如,在图像处理中,如果您想变得更快,请不要重复使用吸气剂,我建议...

Nicolas Zimmermann answered 2020-06-20T05:45:51Z

0 votes

我为保存变量+1。1)可读性胜于性能-您的代码不仅适合您。2)性能可能微不足道,但并非始终如此。 我认为保持一致并树立先例很重要。 因此,尽管对于一个局部变量而言可能无关紧要,但是对于较大的类而言,多次使用相同的值或者在循环的情况下,它可能至关重要。3)易于更改实现/避免使用DRY代码。 现在,您可以使用吸气剂从这一地方获得价值,并且理论上讲,您在一堂课中使用吸气剂100次。 但是在将来-如果您想更改获取值的方式/方式-现在必须将其更改100次,而不是将其另存为实例变量时更改一次。

DLindz answered 2020-06-20T05:46:12Z

java调用方法出现i 2a_性能-Java方法调用与使用变量相关推荐

  1. 提高计算机性能的主流方法,提高电脑内存性能的方法

    提高电脑内存性能的方法 如何优化内存的管理,提高内存的使用效率,尽可能地提高运行速度,这样能让我们的电脑运行的更快,下面小编就来和大家说说提高电脑内存性能的方法吧! 提高电脑内存性能的方法 1.改变页 ...

  2. 大数据量下(批量)提升性能的方法以及常见的性能优化方法

    数据库层面(包含数据库设计和语句):尽量做到节省时间和数据库开销 1.让语句更加合理,符合查询优化的规则.避免全表扫描,建立高效索引,正确利用索引等. 2.避免频繁创建和删除临时表. 3.尽量避免向客 ...

  3. windows服务器性能分析方法小结,Windows服务器性能分析方法小结

    Windows服务器性能各种指标的分析 事情的起因是BOSS/CRM系统的扩容.我所要做得,仅仅是写一份CRM Windows服务器的性能分析,不过这足以让我一筹莫展了,毕竟当时对主机性能分析的认识, ...

  4. Java中四种遍历Map对象的方法

    方法一:在for-each循环中使用entry来遍历,通过Map.entrySet遍历key和value,这是最常见的并且在大多数情况下也是最可取的遍历方式.在键值都需要时使用. Map<Int ...

  5. java面试突击第一季课件,Java开发面试技能介绍

    前言 这几年在Java工程师招聘时,会看到很多人的简历都写着使用了Spring Cloud做微服务实现,使用Docker做自动化部署,并且也会把这些做为自己的亮点.而比较有趣的这其中以小公司出来的人为 ...

  6. Java经典面试题:一个线程两次调用start()方法会出现什么情况?

    大家好,我是 Oracle首席工程师杨晓峰. 今天想和大家深入聊聊线程,相信大家对于线程这个概念都不陌生,它是Java并发的基础元素,理解.操纵.诊断线程是Java工程师的必修课,但是你真的掌握线程了 ...

  7. Java的JVM运行时栈结构和方法调用详解

    详细介绍了Java 的JVM的运行时栈结构,以及和方法调用详解,包括解析调用和分派调用. JVM对于方法的执行是基于栈的,方法调用--入栈,方法调用完毕--出栈,了解JVM的运行时栈结构,有助于我们更 ...

  8. arthas 查看哪个方法调用最耗时_火眼金睛,Java诊断利器Arthas

    1 简介 Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱 当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决: 这个类从哪个 jar 包加载的?为什么会报各种类相关的 ...

  9. android 调用java类_Android中在WebView里实现Javascript调用Java类的方法

    搜索热词 为了方便网页和Android应用的交互,Android系统提供了WebView中JavaScript网页脚本调用Java类方法的机制.只要调用addJavascriptInterface方法 ...

最新文章

  1. spring的钩子_spring--BeanPostProcesstor
  2. 【theano-windows】学习笔记十一——theano中与神经网络相关函数
  3. java8 stream 分组_Java 8 中 Map 骚操作之 merge() 的用法
  4. 125w短波通信距离_125W军用自主选频短波电台
  5. python使用opencv保存视频_Pythone OpenCV学习笔记之:视频文件读取与保存
  6. 保持稳定迭代的秘密:基于Spinnaker的全自动渐进式交付
  7. 《那些年啊,那些事——一个程序员的奋斗史》三
  8. npm error! npm Maxium size exceed
  9. Uplift Model
  10. linux 下显示隐藏文件夹
  11. JQuery图片抽奖
  12. 一脸懵逼学习oracle(图形化界面操作---》PLSQL图形化界面)
  13. 勇敢的心——感动内德
  14. 计算机教学改革模式,计算机专业课程教学改革研究
  15. linux centos安装桌面环境,CentOS6 CentOS7装桌面环境
  16. openssl命令生成根证书和使用根证书签名工作证书
  17. XeLaTeX下LaTeX中文字体加粗解决方案
  18. 力扣416 二维数组解法
  19. 苹果手机屏幕尺寸_苹果,小米在折叠屏手机上曝光新专利,TCL展示卷轴式屏幕手机...
  20. 七、RISC-V SoC内核——总线 代码讲解

热门文章

  1. python秒表代码_斌哥教你自制千分秒表(键盘控制)
  2. sublime text 64位_Python学习第一步 - 用Sublime搭建Python运行环境
  3. Linux的TCP接口介绍
  4. 浅析 C++智能指针和 enable_shared_from_this 机制
  5. 论一切都是文件之匿名 inode
  6. “我把技术负债玩成了俄罗斯方块,却永远赢不了!”
  7. 抖音否认封杀腾讯;程序员拒绝带电脑回家被开除,获赔 19.4 万;Excel 具备图灵完备性 | 极客头条...
  8. 清华毕业生最爱去华为;应届生称因拒绝加班,被申通快递辞退;PrestoSQL被迫更名 | 极客头条...
  9. TypeScript 的存在削弱了 JavaScript 生态系统?
  10. 云、AI、5G技术融合,会将移动互联网带到什么新高度?