【发布时间】:2014-02-16 22:03:29
【问题描述】:
我正在尝试计算方法的字节码大小,因为我想确保它足够小,可以通过编译器优化进行内联。
我看到内联方法的默认最大大小是 35,所以如果方法大于此,我将修改代码或将其分解为多个方法。
我有一个方法可以生成下面的字节码(通过 IntelliJ IDEA 的 ASM Bytecode Outline 插件反汇编)。
我如何知道该方法的字节码大小? LINENUMBER 似乎引用了原始源代码的行号。
public static mergeNativeArrays([Ljava/lang/Object;[Ljava/lang/Object;IZ)[Ljava/lang/Object;
L0
LINENUMBER 865 L0
ALOAD 0
ASTORE 4
L1
LINENUMBER 867 L1
ILOAD 2
IFGE L2
L3
LINENUMBER 868 L3
ALOAD 0
ARRAYLENGTH
ISTORE 2
L2
LINENUMBER 870 L2
FRAME APPEND [[Ljava/lang/Object;]
ILOAD 2
ALOAD 1
ARRAYLENGTH
IADD
ISTORE 5
L4
LINENUMBER 872 L4
ALOAD 4
ARRAYLENGTH
ILOAD 5
IF_ICMPGE L5
L6
LINENUMBER 874 L6
ILOAD 3
IFEQ L7
L8
LINENUMBER 875 L8
ILOAD 5
INVOKESTATIC railo/commons/math/MathUtil.nextPowerOf2 (I)I
ISTORE 5
L7
LINENUMBER 877 L7
FRAME APPEND [I]
ILOAD 5
ANEWARRAY java/lang/Object
ASTORE 4
L9
LINENUMBER 878 L9
ALOAD 0
ICONST_0
ALOAD 4
ICONST_0
ALOAD 0
ARRAYLENGTH
INVOKESTATIC java/lang/System.arraycopy (Ljava/lang/Object;ILjava/lang/Object;II)V
L5
LINENUMBER 881 L5
FRAME SAME
ALOAD 1
ICONST_0
ALOAD 4
ILOAD 2
ALOAD 1
ARRAYLENGTH
INVOKESTATIC java/lang/System.arraycopy (Ljava/lang/Object;ILjava/lang/Object;II)V
L10
LINENUMBER 883 L10
ALOAD 4
ARETURN
L11
LOCALVARIABLE dst [Ljava/lang/Object; L0 L11 0
LOCALVARIABLE src [Ljava/lang/Object; L0 L11 1
LOCALVARIABLE dstPosition I L0 L11 2
LOCALVARIABLE doPowerOf2 Z L0 L11 3
LOCALVARIABLE result [Ljava/lang/Object; L1 L11 4
LOCALVARIABLE newSize I L4 L11 5
MAXSTACK = 5
MAXLOCALS = 6
【问题讨论】:
-
对不起,我的意思是内联。您可以使用 -
XX:+PrintInlining标志。 -
35 字节是不常用方法的默认最大值,如果您经常调用这些方法,则可以内联更大的方法(常用方法的默认值取决于 JVM)。您可以随时增加此数字以查看它提高了代码的性能。
-
我建议使用 javap。
-
确保代码已预热将使性能提高 10-100 倍,远远超过单独的内联。如果您不能确定代码是否已预热,我会采取措施确保关键代码被调用得足够多。
-
让从未被称为更高效的代码有什么意义。除非您清楚地了解您要优化的内容以及显示您所做更改的指标,否则您会迷失方向。你同样有可能让事情变得更糟、更复杂。
标签: java bytecode compiler-optimization java-bytecode-asm