มันอาจส่งผลให้รหัสไบต์ขนาดเล็กลงเล็กน้อยเนื่องจากวิธีการคงที่จะไม่สามารถเข้าถึงthis
ได้ ฉันไม่คิดว่ามันจะสร้างความแตกต่างในด้านความเร็ว (และถ้าเป็นเช่นนั้นมันอาจจะเล็กเกินไปที่จะสร้างความแตกต่างโดยรวม)
ฉันจะทำให้พวกเขาคงที่เนื่องจากฉันทำเช่นนั้นโดยทั่วไปถ้าเป็นไปได้ทั้งหมด แต่นั่นเป็นเพียงฉัน
แก้ไข:คำตอบนี้ยังคงลดลงอาจเป็นเพราะการยืนยันอย่างไม่มีเงื่อนไขเกี่ยวกับขนาด bytecode ดังนั้นฉันจะทำการทดสอบ
class TestBytecodeSize {
private void doSomething(int arg) { }
private static void doSomethingStatic(int arg) { }
public static void main(String[] args) {
// do it twice both ways
doSomethingStatic(0);
doSomethingStatic(0);
TestBytecodeSize t = new TestBytecodeSize();
t.doSomething(0);
t.doSomething(0);
}
}
Bytecode (ดึงข้อมูลด้วยjavap -c -private TestBytecodeSize
):
Compiled from "TestBytecodeSize.java"
class TestBytecodeSize extends java.lang.Object{
TestBytecodeSize();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
private void doSomething(int);
Code:
0: return
private static void doSomethingStatic(int);
Code:
0: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: invokestatic #2; //Method doSomethingStatic:(I)V
4: iconst_0
5: invokestatic #2; //Method doSomethingStatic:(I)V
8: new #3; //class TestBytecodeSize
11: dup
12: invokespecial #4; //Method "<init>":()V
15: astore_1
16: aload_1
17: iconst_0
18: invokespecial #5; //Method doSomething:(I)V
21: aload_1
22: iconst_0
23: invokespecial #5; //Method doSomething:(I)V
26: return
}
อัญเชิญวิธีการคงใช้เวลาสอง bytecodes (byteops?): iconst_0
(สำหรับอาร์กิวเมนต์) invokestatic
และ
อัญเชิญวิธีการไม่คงต้องใช้เวลาสาม: aload_1
(สำหรับTestBytecodeSize
วัตถุที่ผมคิดว่า) iconst_0
(สำหรับอาร์กิวเมนต์) invokespecial
และ (โปรดทราบว่าหากวิธีการเหล่านี้ไม่ได้เป็นวิธีส่วนตัวก็คงจะเป็นinvokevirtual
แทนที่จะinvokespecial
ดูJLS .77.7 วิธีเรียกใช้ )
ตอนนี้อย่างที่ฉันพูดฉันไม่ได้คาดหวังว่าจะมีความแตกต่างอย่างมากในประสิทธิภาพการทำงานระหว่างสองสิ่งนี้นอกเหนือจากความจริงที่invokestatic
ต้องใช้รหัสน้อยกว่าหนึ่งรหัส invokestatic
และinvokespecial
ทั้งคู่ควรจะเร็วกว่าเล็กน้อยinvokevirtual
เนื่องจากทั้งคู่ใช้การรวมแบบคงที่แทนที่จะเป็นแบบไดนามิก แต่ฉันไม่รู้ว่าถ้าเร็วกว่าแบบอื่น ฉันไม่พบการอ้างอิงที่ดีใด ๆ บทความที่ใกล้เคียงที่สุดที่ฉันสามารถค้นหาได้คือบทความ JavaWorld 1997ซึ่งโดยทั่วไปจะปรับปรุงสิ่งที่ฉันเพิ่งพูดว่า:
คำแนะนำที่เร็วที่สุดจะเป็นไปได้มากที่สุดinvokespecial
และinvokestatic
เนื่องจากวิธีการที่เรียกใช้โดยคำแนะนำเหล่านี้ถูกผูกไว้แบบคงที่ เมื่อ JVM แก้ไขการอ้างอิงสัญลักษณ์สำหรับคำแนะนำเหล่านี้และแทนที่ด้วยการอ้างอิงโดยตรงการอ้างอิงโดยตรงนั้นอาจจะรวมถึงตัวชี้ไปยังไบต์จริง
แต่มีหลายสิ่งเปลี่ยนไปตั้งแต่ปี 1997
สรุปแล้ว ... ฉันเดาว่าฉันยังคงยึดติดกับสิ่งที่ฉันพูดไว้ก่อนหน้านี้ ความเร็วไม่ควรเป็นเหตุผลในการเลือกอย่างใดอย่างหนึ่งเนื่องจากมันจะเป็นการเพิ่มประสิทธิภาพขนาดเล็กที่ดีที่สุด