自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java 中反射、內(nèi)省的性能差距居然如此

開發(fā) 前端
基準(zhǔn)測試的幾種情況已經(jīng)準(zhǔn)備好了,為了達(dá)到更充分的驗(yàn)證,我們分別循環(huán)執(zhí)行10、100、200、500次,我們跑一下基準(zhǔn)測試看看效果。

你好,我是看山。

今天我們通過基準(zhǔn)測試驗(yàn)證下到底有多慢。

結(jié)果是我萬萬沒想到的,跑了好幾遍基準(zhǔn)測試,不得不承認(rèn)之前是自己不嚴(yán)謹(jǐn)了。

演示代碼

先定義使用場景:為一個(gè)JavaBean的屬性賦值。

@Data
public static class User {
    private String username;
    private int level;
}

為User的屬性賦值,我們有三種方式。

原生方式,作為基準(zhǔn):

final User user = new User();
user.setUsername("看山");
user.setLevel(100);

通過反射:

final Class<User> clazz = User.class;
final Constructor<User> constructor = clazz.getConstructor();
final User user = constructor.newInstance();

final Field usernameField = clazz.getDeclaredField("username");
usernameField.setAccessible(true);
usernameField.set(user, "看山");
final Field levelField = clazz.getDeclaredField("level");
levelField.setAccessible(true);
levelField.set(user, 100);

反射也可以通過調(diào)用setter方法賦值:

final Class<User> clazz = User.class;
final Constructor<User> constructor = clazz.getConstructor();
final User user = constructor.newInstance();

final Method setUsernameMethod = clazz.getMethod("setUsername", String.class);
setUsernameMethod.invoke(user, "看山");
final Method setLevelMethod = clazz.getMethod("setLevel", int.class);
setLevelMethod.invoke(user, 100);

使用內(nèi)省賦值:

final BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
final User user = new User();

final PropertyDescriptor[] props = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor prop : props) {
    if ("username".equals(prop.getName())) {
        final Method method = prop.getWriteMethod();
        method.invoke(user, "看山");
    } else if ("level".equals(prop.getName())) {
        final Method method = prop.getWriteMethod();
        method.invoke(user, 100);
    }
}

內(nèi)省方式也可以直接指定屬性:

final User user = new User();

final PropertyDescriptor usernameProp = new PropertyDescriptor("username", User.class);
final Method usernameWriteMethod = usernameProp.getWriteMethod();
usernameWriteMethod.invoke(user, "看山");

final PropertyDescriptor levelProp = new PropertyDescriptor("level", User.class);
final Method levelWriteMethod = levelProp.getWriteMethod();
levelWriteMethod.invoke(user, 100);

好了,基準(zhǔn)測試的幾種情況已經(jīng)準(zhǔn)備好了,為了達(dá)到更充分的驗(yàn)證,我們分別循環(huán)執(zhí)行10、100、200 、500次,我們跑一下基準(zhǔn)測試看看效果。

測試效果

保留下500次循環(huán)的數(shù)據(jù)(回復(fù):Java可以獲取源碼)

Benchmark                                                           Score        Error    
BeanSetJmhTest.testBase                                           671.299 ±     14.201    基準(zhǔn)
BeanSetJmhTest.testAccessFieldCacheByReflectField                6451.184 ±    212.541    反射-緩存-屬性賦值
BeanSetJmhTest.testMethodCacheByReflect                         13381.968 ±   1921.017    反射-緩存-方法賦值
BeanSetJmhTest.testMethodCacheByIntrospector                    13523.807 ±   2146.288    內(nèi)省-緩存-方法賦值
BeanSetJmhTest.testMethodByReflect                              44874.497 ±  14215.009    反射-方法賦值
BeanSetJmhTest.testAccessFieldByReflect                         57989.549 ± 282731.822    反射-屬性賦值
BeanSetJmhTest.testAccessFieldCacheByIntrospectorDirectProp    121879.007 ±  28027.596    內(nèi)省-緩存-指定屬性賦值
BeanSetJmhTest.testAccessFieldCacheByIntrospectorProps         167602.264 ±  30272.412    內(nèi)省-緩存-屬性循環(huán)賦值
BeanSetJmhTest.testAccessFieldByIntrospectorProps              204765.110 ±  53973.520    內(nèi)省-屬性循環(huán)賦值
BeanSetJmhTest.testAccessFieldByIntrospectorDirectProp         783250.528 ±  40212.597    內(nèi)省-指定屬性賦值

可視化結(jié)果:

基準(zhǔn)測試結(jié)果基準(zhǔn)測試結(jié)果

從結(jié)果看:

  1. 在設(shè)置屬性方面,反射性能優(yōu)于內(nèi)??;【上面結(jié)果是在JDK21測試的,試過JDK8、JDK17結(jié)果相似,不太確定有些文章說的內(nèi)省性能優(yōu)于反射是怎么測試的?!浚?/li>
  2. 有緩存的邏輯性能會明顯優(yōu)于沒有緩存的邏輯,無論是反射還是內(nèi)省;
  3. 非必要情況,不要使用反射和內(nèi)省,直接用JavaBean的setter賦值,性能差的太多。

責(zé)任編輯:武曉燕 來源: 看山的小屋
相關(guān)推薦

2025-01-20 00:00:00

反射Java語言

2010-03-12 08:55:06

Java內(nèi)省反射

2021-07-11 09:34:45

ArrayListLinkedList

2025-01-10 00:00:00

內(nèi)省機(jī)制JavaBean描述器

2009-07-14 18:09:08

Jython的內(nèi)省

2024-01-17 10:05:09

Python內(nèi)省反射機(jī)制

2011-02-28 09:51:43

內(nèi)省

2011-05-25 14:46:16

程序員

2011-09-27 10:23:24

Java反射機(jī)制

2010-03-10 18:42:30

Python性能

2017-09-12 15:30:31

2023-04-10 07:26:28

UseStateUseReducer

2022-06-24 09:41:37

制造業(yè)技能物聯(lián)網(wǎng)

2011-07-01 15:04:49

Qt 內(nèi)省

2010-05-07 17:50:31

Unix服務(wù)器

2009-02-03 09:42:53

JAVA類JVM指令forName方法

2025-01-13 12:00:00

反射Java開發(fā)

2024-06-04 00:00:30

C#反射編程

2010-09-26 09:20:39

JVM1.6JVM1.5

2023-07-05 14:38:09

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號