`
sunqi
  • 浏览: 227942 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

map or switch

阅读更多

最近碰到个场景,还蛮有普遍性的,如简单工厂方法,需要依据入参选择不同的业务逻辑进行对应的处理

 

马上想到两个方案

方案一:采用map存放对应入口的处理方法,然后请求进来后经过get就行,map.get(et);

方案二:采用switch语句,

              switch (et) {

              case API3:

                     return api3service;

              case API4:

                     return api4service;

              case API2:

                     return api2service;

              ……

 

if else这种就不予考虑了

 

明显采用map显的更优雅,代码更具可维护性,如果用switch每次需要硬编码

那性能呢?

 

但用map,也可以做些优化处理,比如我发现一些入参在map默认大小为16下,其桶位置发生了碰撞,这样每次get

的时候就需要遍历了,这是不好,当然有两种方案,一是改key值避免碰撞,二是改map大小,让其不发生碰撞,

我采用map大小为64,避免碰撞,当然后面如要继续添加时候,需要关注

经测试,性能可以提升44%,(本机场景,并且这个key在桶的最尾部,也就是需要全部遍历桶全部数据的场景,并且全部预先执行1w次,摒弃了jit对结果的影响)

 

mapget操作,每次需要进行hash,位移操作,&操作,再比较操作,想想就需要很多的指令要执行完才能拿到

 

如果是switch呢?

Switch在编译后,有LookupSwitch TableSwitch,其中TableSwitchO(1)的,LookupSwitch O(log n) 

 

TableSwitch情况

int chooseNear(int i) {
    switch (i) {
        case 0:  return  0;
        case 1:  return  1;
        case 2:  return  2;
        default: return -1;
    }
}

编译后结果

Method int chooseNear(int)
0   iload_1             // Push local variable 1 (argument i)
1   tableswitch 0 to 2: // Valid indices are 0 through 2
      0: 28             // If i is 0, continue at 28
      1: 30             // If i is 1, continue at 30
      2: 32             // If i is 2, continue at 32
      default:34        // Otherwise, continue at 34
28  iconst_0            // i was 0; push int constant 0...
29  ireturn             // ...and return it
30  iconst_1            // i was 1; push int constant 1...
31  ireturn             // ...and return it
32  iconst_2            // i was 2; push int constant 2...
33  ireturn             // ...and return it
34  iconst_m1           // otherwise push int constant -1...
35  ireturn             // ...and return it

 

也就是TableSwitch只要计算一次偏移量,立即就能到case执行,其时间复杂度为O(1) 

 

LookupSwitch

int chooseFar(int i) {
    switch (i) {
        case -100: return -1;
        case 0:    return  0;
        case 100:  return  1;
        default:   return -1;
    }
}

编译后:

Method int chooseFar(int)
0   iload_1
1   lookupswitch 3:
         -100: 36
            0: 38
          100: 40
      default: 42
36  iconst_m1
37  ireturn
38  iconst_0
39  ireturn
40  iconst_1
41  ireturn
42  iconst_m1
43  ireturn

 

也就是LookupSwitch编译后会保证其顺序,并采用二分法查找对应的case,其时间复杂度为O(log n) 

本机,全部预先执行1w次跳过jit的影响,采用mapswitch各执行1亿次,执行时间是两位数的差距,map400msswitch5ms

 

当然测试的场景case都比较少,如果达到1k多个case条件呢? Jit还会把jvm指令缓存吗?,如果不缓存又是另外的情况了

大家可以把eclipse设置Xint,看看屏蔽jit后大量运行的效果

还有switch在什么场景下编译后会是TableSwitch,什么下会是LookupSwitch,毕竟两者的时间复杂度还是有差距

Java应用的性能,还是要详细分析其场景,至于要性能还是代码更优雅,要自己权衡了,呵呵,有更好的方案,还请分享哦

 

参考资料

 

http://stackoverflow.com/questions/10287700/difference-between-jvma-lookupswitch-and-tableswitch

 

http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-3.html#jvms-3.10

分享到:
评论

相关推荐

    bit map 苹果手机户外导航

    Store multiple maps on your iPhone or iPad, and switch between them. With Bit Map, you can view your own choice of maps, instead of generic maps chosen by somebody else, making it ideal

    ReactFastMap:单例地图组件,只需要初始化一次,就能无缝切换地图,避免组件切换带来的频繁地图初始化。A single instance map component that allow you switch the component frequently with no re-initialize

    Even if the pages switch frequently, the Map Component don't need to wait rendering. Basic Usage Install npm i react-fast-map // or yarn add react-fast-map 1. Import API file // 1. 在/public/index....

    swstp 快速生成树协议

    based on the IEEE 802.1D standard and Cisco proprietary extensions, or the rapid per-VLAN spanning-tree plus (rapid-PVST+) protocol based on the IEEE 802.1w standard. For information about the ...

    RealToon 5.2.1 卡通动漫风格着色器.txt

    *(This is not a matcap style reflection or cubemap.) - Outline: *(Can change the Color and Width) *(With noise/distort outline for sketch style outline and dynamic) *(You can choose to use outline or...

    javascript中break,continue和return语句用法小结

    break,continue和return这三个语句的用法新手们经常弄混淆,至少在我学习c语言的时候经常把它们的用法给搞错。不过现在好了,我已彻底搞清楚它们之间的用法

    MS-DOS 5.0

    ROM BIOS to version 1.21 or later. The ROM BIOS version number is displayed when you start your computer. 2.14 LANtastic -------------- If you use a LANtastic network, disable it before running Setup...

    eac3to V3.17

    * added undocumented "-no2ndpass" switch to turn off 2nd pass processing * fixed: two pass processing sometimes produced superfluous sup files * fixed: MPG/EVO/VOB audio tracks with "PES extension 2" ...

    lrucacheleetcode-thinking-in-algorithm:flag:7天入门数据结构与算法

    or map) 二维数据结构 基础:树tree,图graph 高级:二叉搜索树binary search tree(red-black tree,AVL),堆heap,并查集disjoint set,字典树Trie 特殊数据结构 位运算Bitwise,布隆过滤器BloomFilter LRU Cache ...

    最完整的Toad For Oracle使用手册

    Log Switch Frequency Map 194 Tablespace Map 194 TKProf Interface Wizard 196 Undo Advisor 198 Segment Advisor 200 LogMiner Interface 203 Health Check 207 Trace File Browser 226 CodeXpert 231 Database ...

    hls.min.js

    MANIFEST_LOADING:"hlsManifestLoading",MANIFEST_LOADED:"hlsManifestLoaded",MANIFEST_PARSED:"hlsManifestParsed",LEVEL_SWITCH:"hlsLevelSwitch",LEVEL_SWITCHING:"hlsLevelSwitching",LEVEL_SWITCHED:...

    javalruleetcode-thinkermaster-arithmetic:学习算术并将其公开到thinkermaster.com

    or map), etc 二维 基础: 树tree, 图graph 二叉搜索树 binary search tree, 红黑树(red-black tree, AVL), 堆heap, 并查集disjoint set, 字典树 Trie, etc 特殊 位运算Bitwise, 布隆过滤器BloomFilter LRU Cache ...

    Practical C++ Programming C++编程实践

    Standard Template Library STL Basics Class List-A Set of Students Creating a Waiting List with the STL List Storing Grades in a STL Map Putting It All Together Practical Considerations When Using the...

    校园导游图程序

    \nplease press b or s or e.\n");getchar();break; } Star()函数:主要是显示一个界面,功能是提供查询路径选择和查看进入景点的主页面和退出该页面返回主界面。 switch(choose) {case '0':instruction();...

    i-vector的工具箱

    The logical switch varnorm (false | true) is used to instruct the code to perform variance normalization in addition to mean normalization. Examples In an example we plot the distribution (histogram...

    Google C++ Style Guide(Google C++编程规范)高清PDF

    Another useful rule of thumb: it's typically not cost effective to inline functions with loops or switch statements (unless, in the common case, the loop or switch statement is never executed)....

    Creating the OutLookRichEdit Control

    Call AfxInitRichEdit() in the InitInstance of the App class or in InitDialog. If it does not exist, copy OutLookRichEdit.cpp and OutLookRichEdit.h to the project directory. Click the menu choice ...

    degital electronics

    6.6.2 Karnaugh Map for Boolean Expressions with a Larger Number of Variables 222 6.6.3 Karnaugh Maps for Multi-Output Functions 225 Review Questions 230 Problems 230 Further Reading 231 7 Arithmetic ...

    k7 SRIO参考例程

    - GUI settings incorrect or not properly reflected in hardware. - Version fixed : v5.4 - CR#507334, CR#528369, CR#528370 / AR#32122 - The following register fields were corrected: Re-transmit ...

    Scala for the Impatient 2nd (完整英文第二版 带书签)

    14.1 A Better Switch 198 14.2 Guards 199 14.3 Variables in Patterns 199 14.4 Type Patterns 200 14.5 Matching Arrays, Lists, and Tuples 201 14.6 Extractors 202 14.7 Patterns in Variable Declarations ...

    PLX PCI卡 linux驱动

    to map a PCI BAR space directly to the application's virtual space. The application can then directly access the space via simple memory dereferencing, bypassing the PLX API/driver & resulting in ...

Global site tag (gtag.js) - Google Analytics