我很难理解Java字节码中的LoopUpwitter和TabLeSwitCH。

如果我理解得很好,LoopUpTwitter和TabLaswitCH都对应于Java源的EDCOX1×0语句吗?为什么一个Java语句生成2个不同的字节码?

Jasmin文件:

查找开关

桌上女巫

区别在于lookupswitch使用带有键和标签的表,而tableswitch只使用带有标签的表。

在执行tableswitch时,堆栈顶部的int值直接用作表中的索引,以获取跳转目标并立即执行跳转。整个lookup+jump过程是一个O(1)操作,这意味着它的速度非常快。

执行lookupswitch时,将堆栈顶部的int值与表中的键进行比较,直到找到匹配项,然后使用该键旁边的跳转目标执行跳转。由于lookupswitch表总是必须进行排序,因此对于每个x编译器根据switch语句的紧凑程度来决定要使用哪条指令,例如:

switch (inputValue) {

case 1:  // ...

case 2:  // ...

case 3:  // ...

default: // ...

}

上面的开关非常紧凑,没有数字"孔"。编译器将创建这样的表开关:

tableswitch 1 3

OneLabel

TwoLabel

ThreeLabel

default: DefaultLabel

Jasmin页面的伪代码很好地解释了这一点:

int val = pop();                // pop an int from the stack

if (val < low || val > high) {  // if its less than or greater than ,

pc += default;              // branch to default

} else {                        // otherwise

pc += table[val - low];     // branch to entry in table

}

这段代码非常清楚这种TableSwitch是如何工作的。val为inputValue,low为1(交换机中的最低case值),high为3(交换机中的最高case值)。

即使有一些孔,开关也可以很紧凑,例如

switch (inputValue) {

case 1:  // ...

case 3:  // ...

case 4:  // ...

case 5:  // ...

default: // ...

}

上面的开关"几乎紧凑",只有一个孔。编译器可以生成以下指令:

tableswitch 1 6

OneLabel

FakeTwoLabel

ThreeLabel

FourLabel

FiveLabel

default: DefaultLabel

; <...code left out...>

FakeTwoLabel:

DefaultLabel:

; default code

如您所见,编译器必须为2添加一个假的case,FakeTwoLabel。因为2不是开关的实际值,所以faketwLabel实际上是一个标签,它可以准确地更改代码流默认情况所在的位置,因为值2实际上应该执行默认情况。

因此,对于编译器创建TableSwitch来说,开关并不一定要非常紧凑,但它至少应该非常接近紧凑性。现在考虑以下开关:

switch (inputValue) {

case 1:    // ...

case 10:   // ...

case 100:  // ...

case 1000: // ...

default:   // ...

}

这个开关几乎没有紧凑性,它有超过百倍的洞比值多。我们可以称之为备用开关。编译器将不得不生成近千个伪案例来将此开关表示为TableSwitch。结果将是一个巨大的表,极大地放大了类文件的大小。这是不实际的。相反,它将生成一个lookupswitch:

lookupswitch

1       : Label1

10      : Label10

100     : Label100

1000    : Label1000

default : DefaultLabel

这个表只有5个条目,而不是1000多个条目。该表有4个实数,o(log 4)是2(这里的log 2是以btw为基,而不是以10为基,因为计算机是用二进制数操作的)。这意味着,VM最多需要两个比较来查找输入值的标签或得出结论,即该值不在表中,因此必须执行默认值。即使该表有100个条目,也最多需要7个比较,才能找到正确的标签或决定跳到默认标签(7个比较远小于100个比较,您不认为吗?).

所以,这两个指令是可以互换的,或者两个指令的原因有历史原因,这是无稽之谈。对于两种不同的情况,有两种指令,一种用于具有紧凑型值(最大速度)的开关,另一种用于具有备用值(不是最大速度,但仍然具有良好的速度和非常紧凑的表表示,不管所有数字孔如何)。

对于任何大于对数基数的n,n*log(n)大于n,我认为这通常比我们正在评估的n的大小要小得多;即,O(n)比O(n log n)更好。

@FauxFaux:谢谢你的信息,我已经相应地修改了回复。

更准确地说,它javac 8为时间复杂度赋予3个权重,为空间复杂度赋予1个权重:stackoverflow.com/a/31032054/895245

"这里的日志是以2 btw为底的,而不是以10为底的,因为计算机操作二进制数"-我不认为二进制数系统在这里起任何作用。只是每次搜索的集合被减半,因此日志的基数是2。

只是想说,tableswitch不是o(1),至少在实践中不是,根据一些测试,它是线性的。请参见以下网址:github.com/frostwire/frostwire jlibtorrent/pull/&hellip;

@古巴特隆很抱歉,但您的基准测试方法无效。您甚至没有使用查找结果,导致JIT编译器部分优化了整个查找。如果你做得正确,查找0-9和查找0-99之间几乎没有区别。表查找速度更快的原因也不足为奇:内存查找到甚至可以放入CPU的第一级缓存的表中自然是超快速的。代码跳转从来没有那么快,特别是在CPU无法预测的情况下(对于CPU来说,开关通常是不可预测的,与代码中的if/else测试相反)。

@这里有两个修正的基准。查找0-9:ideone.com/cg0cuw,查找0-99:ideone.com/fsehcn。请参阅联机运行时。第一个是50 ms和1181 ms,第二个是50 ms和1215 ms。怎么会是O(N)?O(n)意味着它必须慢10倍。上次在我的系统上运行NUM_INDEXES的100000的索引(比上面的索引多10倍,在托管服务上运行时间不能超过5秒!)685 ms和12168 ms用于0-9和680 ms和12515 ms用于0-99(记住,总是有波动的)。

实际上,它肯定不是O(1),比O(n):更糟糕的是,如果你有很多不适合你的CPU的情况,那就用我说的数组,我们的库就是这样。

@Gubatron切换算法本身是O(1)。如果它在系统上变慢,那么这是由该系统的限制造成的(例如,CPU的代码缓存大小)。决定分支在O(1)时间内发生在何处,通常情况下,只有分支可以变慢(如果是缓存未命中)。您可以在上面自己的Github链接中找到更详细的解释(请参阅最后一条评论)。这里有一个1000:ideone.com/xhesfk的版本,它只是稍微慢一点。增长的代码不能超过O(1);增长的通常是数据,而不是代码!

当正确的Javac 1.8.0 45 Compile开关到Either One?

决定何时使用,您可以使用javac选择算法作为基础。

我们知道javac的来源在langtools中。

然后我们抓住

hg grep -i tableswitch

第一个结果是Langtools/SRC/share/classes/com/sun/tools/javac/jvm/gen.java:

ZZU1

哪里

最大值

最小案例价值

因此,我们得出结论认为,这既考虑到时间的复杂性,也考虑到空间的复杂性,同时考虑到时间的复杂性,加权为3。

自从有了tableswitch之后,我不明白为什么会有二进制搜索。

奖金:C++++++执行还可以在O(1)Jump Table和O(Long(n))二进制搜索之间进行模拟选择:在if-else Statement上的开关优势

+1因为这有助于我了解如何在自己的JVM语言编译器中实现开关指令。

O(log(n))的时间不一定更好,总是有一些乘法器,因此C1*N*C2*log(n)可以发生在N< Java选择扫描和C3* 1 < C2*log(n)中,用于n>=Java选择索引。但是索引可能会浪费空间。

Java虚拟机规范描述了差异。当开关的事例可以有效地表示为目标偏移表中的索引时,使用table switch指令。"该规范描述了更多详细信息。

由于Java字节码与下划线的机器代码(例如Sun自己的CPU)的某种特定绑定,所以我怀疑它大部分是历史的。

tableswitch本质上是一个计算跳转,其中目的地是从查找表中获取的。相反,lookupswitch需要对每个值进行比较,基本上是通过表元素进行迭代,直到找到匹配的值。

显然,这些操作码是可互换的,但基于值,其中一个或另一个操作码可以更快或更紧凑(例如,比较键组与键组之间有较大间隙的键组)。

java switch table_关于java:JVM的LookupSwitch和TableSwitch之间的区别?相关推荐

  1. Java 中访问数据库的步骤?Statement 和PreparedStatement 之间的区别?

    Java 中访问数据库的步骤?Statement 和PreparedStatement 之间的区别? Java 中访问数据库的步骤 1)注册驱动: 2)建立连接: 3)创建Statement: 4)执 ...

  2. 关于JAVA Bean实体类对象pojo,vo,po,dto,entity之间的区别

    关于JAVA Bean实体类对象pojo,vo,po,dto,entity之间的区别: Pojo: Pojo 普通的java对象 最基本的javaBean只有属性 加上属性的get,set方法,可以转 ...

  3. 初学JAVA 基础(二)JVM、JRE、JDK之间的关系

    JDK: java开发工具 (java Development Kit) JDK的 下载与安装 JDK是整个JAVA的核心,包括了Java运行环境(JRE),一堆Java工具(javac/java/j ...

  4. java中separator_java - File.separator和路径中的斜杠之间的区别

    java - File.separator和路径中的斜杠之间的区别 在Java Path-String中使用/和普通的File.separator有什么区别? 与双反斜杠相比,/平台独立似乎不是原因, ...

  5. Java中WeakReference,SoftReference,PhantomReference和Strong Reference之间的区别

    很长一段时间以来,WeakReference和SoftReference都已添加到Java API中,但是并不是每个Java程序员都熟悉它. 这意味着在Java中使用WeakReference和Sof ...

  6. java的jbutton啥意思,Jbutton和Jpanel和JFrame之间的区别?

    我制作简单的游戏,它由2个文件组成,第一个文件是"Alibaba.java",它是从JFrame扩展的,我用它来显示游戏的一般内容! 第二个文件是"intro.java& ...

  7. Java中Int、Integer、new Integer()之间的区别

    Java中有八种基本数据类型,Int是其中之一.而Integer是Int的封装,即Integer其实是一个对象.可以通过new来创建一个Integer对象,也可以直接将Int值赋给Integer变量. ...

  8. java switch null_[改善Java代码]小心switch带来的空值异常

    使用枚举定义常量时,会伴有大量的switch语句判断,目的是伪类每个枚举项解释其行为,例如: 1 public classClient {2 public static voidmain(String ...

  9. java table 设置长度_Java字节码lookupswitch和tableswitch总指令长度

    使用给定的字节码,当遇到切换指令时,我想知道下一条指令的位置(不运行代码).为了做到这一点,我想我应该计算指令的总大小,包括跳转偏移或匹配偏移对.这可能吗?如果不是,怎么可能知道下一条指令在哪里? 此 ...

最新文章

  1. Java中sin、log、tan等复杂数学运算怎么搞?
  2. input type=file change事件只触发一次
  3. hdu1435 稳定婚姻问题
  4. C++总结篇(5)vector
  5. Ubuntu crontab 定时 python 详细
  6. 曾估值 45 亿美元!Apache Kafka 商业化公司 Confluent 计划上市:已申请 IPO
  7. 遇到win7系统电脑没有声音了怎么解决
  8. Zabbix 监控网站的访问量
  9. kickstart注意事项
  10. C++程序设计(二:机器模拟)
  11. Linux下rpm安装jdk17
  12. 478.在圆内随机生成点
  13. stm32以中断方式扫描矩阵键盘
  14. 我用10张图总结出了这份并发编程最佳学习路线!!(建议收藏)
  15. [蓝桥杯Python]:跑步训练----小蓝每天都锻炼身体。正常情况下,小蓝每天跑1千米。如果某天是周一或者月初(1日),为了激励自己,小蓝要跑2千米。如果同时是周一-或月初,小蓝也是跑2千米。小蓝
  16. css文字闪光特效,利用js css3实现文字闪光滑过动画特效
  17. C语言写一个猜数字游戏?我只想玩王者荣耀
  18. 做一个很出色的程序员
  19. python调用百度AI识别文字和表格
  20. Android输入法官方SoftKeyboard示例解析

热门文章

  1. 北京有这些互联网公司,你都知道么?
  2. VMware Network Adapter VMnet8 没有有效的 IP 配置
  3. 六西格玛管理的六个主题
  4. 分水果(冬季每日一题 21)
  5. LSTM的加速算法:QRNN和SRU
  6. hive经典指标:最近7天连续3天活跃用户数
  7. 自动售货机 顺序图_饮料销售机UML顺序图
  8. C# Net6开发Linux守护进程(后台服务程序,类似Windows服务)案例
  9. 6个关键点打造适合自己的人设,抖音带货直播必备技能,送人设模板
  10. java ora-12505_JDBC连接Oracle数据库时出现的ORA-12505错误及解决办法