ฉันยังใหม่กับ java และใช้รหัสบางคืนเมื่อคืนและนี่รบกวนฉันจริงๆ ฉันกำลังสร้างโปรแกรมง่าย ๆ เพื่อแสดงเอาต์พุต X ทุกอันในลูป for และฉันสังเกตเห็นว่าประสิทธิภาพลดลงอย่างมากเมื่อฉันใช้โมดูลัสเป็นvariable % variablevs variable % 5000หรือ whatnot มีคนอธิบายให้ฉันฟังได้ไหมว่าเพราะอะไรและสาเหตุคืออะไร ดังนั้นฉันจะดีกว่า ...
นี่คือรหัส "ประสิทธิภาพ" (ขออภัยถ้าฉันได้รับไวยากรณ์เล็กน้อยผิดฉันไม่ได้อยู่ในคอมพิวเตอร์ด้วยรหัสตอนนี้)
long startNum = 0;
long stopNum = 1000000000L;
for (long i = startNum; i <= stopNum; i++){
    if (i % 50000 == 0) {
        System.out.println(i);
    }
}
นี่คือ "รหัสไม่มีประสิทธิภาพ"
long startNum = 0;
long stopNum = 1000000000L;
long progressCheck = 50000;
for (long i = startNum; i <= stopNum; i++){
    if (i % progressCheck == 0) {
        System.out.println(i);
    }
}
โปรดทราบว่าฉันมีตัวแปรวันที่เพื่อวัดความแตกต่างและเมื่อมันนานพอตัวแรกจะใช้เวลา 50 มิลลิวินาทีในขณะที่อีกอันใช้เวลา 12 วินาทีหรืออย่างนั้น คุณอาจจะต้องเพิ่มstopNumหรือลดระดับprogressCheckหากพีซีของคุณมีประสิทธิภาพมากกว่าของฉันหรืออะไรก็ตาม
ฉันมองหาคำถามนี้ในเว็บ แต่ฉันไม่สามารถหาคำตอบได้บางทีฉันอาจจะไม่ได้ถามก็ได้
แก้ไข: ฉันไม่ได้คาดหวังว่าคำถามของฉันจะได้รับความนิยมฉันชื่นชมคำตอบทั้งหมด ฉันทำการวัดประสิทธิภาพในแต่ละครึ่งของเวลาและรหัสที่ไม่มีประสิทธิภาพใช้เวลานานกว่า 1/4 ของวินาทีกับ 10 วินาทีหรือให้ ได้รับพวกเขากำลังใช้ println แต่พวกเขาทั้งสองทำในปริมาณที่เท่ากันดังนั้นฉันจะไม่คิดว่ามันจะเอียงมากโดยเฉพาะอย่างยิ่งเนื่องจากความแตกต่างสามารถทำซ้ำได้ สำหรับคำตอบเนื่องจากฉันยังใหม่กับ Java ฉันจะให้คะแนนตัดสินใจตอนนี้คำตอบที่ดีที่สุด ฉันจะพยายามเลือกวันพุธ
EDIT2: ฉันจะทำการทดสอบอื่นคืนนี้แทนโมดูลัสมันแค่เพิ่มตัวแปรและเมื่อมาถึง progressCheck มันจะดำเนินการอย่างใดอย่างหนึ่งแล้วรีเซ็ตตัวแปรเป็น 0 สำหรับตัวเลือกที่ 3
EDIT3.5:
ฉันใช้รหัสนี้และด้านล่างฉันจะแสดงผลลัพธ์ของฉัน .. ขอบคุณทุกท่านสำหรับความช่วยเหลือที่ยอดเยี่ยม! ฉันยังลองเปรียบเทียบค่าสั้น ๆ ของความยาวเป็น 0 ดังนั้นเช็คใหม่ของฉันจะเกิดขึ้นตลอดเวลา "65536" ครั้งทำให้เท่ากันซ้ำ
public class Main {
    public static void main(String[] args) {
        long startNum = 0;
        long stopNum = 1000000000L;
        long progressCheck = 65536;
        final long finalProgressCheck = 50000;
        long date;
        // using a fixed value
        date = System.currentTimeMillis();
        for (long i = startNum; i <= stopNum; i++) {
            if (i % 65536 == 0) {
                System.out.println(i);
            }
        }
        long final1 = System.currentTimeMillis() - date;
        date = System.currentTimeMillis();
        //using a variable
        for (long i = startNum; i <= stopNum; i++) {
            if (i % progressCheck == 0) {
                System.out.println(i);
            }
        }
        long final2 = System.currentTimeMillis() - date;
        date = System.currentTimeMillis();
        // using a final declared variable
        for (long i = startNum; i <= stopNum; i++) {
            if (i % finalProgressCheck == 0) {
                System.out.println(i);
            }
        }
        long final3 = System.currentTimeMillis() - date;
        date = System.currentTimeMillis();
        // using increments to determine progressCheck
        int increment = 0;
        for (long i = startNum; i <= stopNum; i++) {
            if (increment == 65536) {
                System.out.println(i);
                increment = 0;
            }
            increment++;
        }
        //using a short conversion
        long final4 = System.currentTimeMillis() - date;
        date = System.currentTimeMillis();
        for (long i = startNum; i <= stopNum; i++) {
            if ((short)i == 0) {
                System.out.println(i);
            }
        }
        long final5 = System.currentTimeMillis() - date;
                System.out.println(
                "\nfixed = " + final1 + " ms " + "\nvariable = " + final2 + " ms " + "\nfinal variable = " + final3 + " ms " + "\nincrement = " + final4 + " ms" + "\nShort Conversion = " + final5 + " ms");
    }
}
ผล:
- fixed = 874 ms (ปกติประมาณ 1,000 มิลลิวินาที แต่เร็วขึ้นเนื่องจากมันเป็นกำลัง 2)
 - ตัวแปร = 8590 ms
 - ตัวแปรสุดท้าย = 1944 ms (คือ ~ 1000ms เมื่อใช้ 50000)
 - increment = 1904 ms
 - การแปลงสั้น = 679 ms
 
ไม่น่าแปลกใจที่เพียงพอเนื่องจากขาดการแบ่งแยกการแปลงสั้นจึงเร็วกว่าวิธีที่ "เร็ว" 23% นี่เป็นเรื่องที่น่าสนใจ หากคุณต้องการแสดงหรือเปรียบเทียบทุก ๆ 256 ครั้ง (หรือประมาณนั้น) คุณสามารถทำได้และใช้
if ((byte)integer == 0) {'Perform progress check code here'}
หมายเหตุสุดท้ายที่น่าสนใจโดยใช้โมดูลัสของ "ตัวแปรที่ประกาศครั้งสุดท้าย" กับ 65536 (ไม่ใช่ตัวเลขที่สวย) คือความเร็วครึ่งหนึ่งของ (ช้ากว่า) กว่าค่าคงที่ ที่ไหนก่อนที่มันจะถูกเปรียบเทียบใกล้กับความเร็วเดียวกัน
finalด้านหน้าของprogressCheckตัวแปรทั้งคู่ก็วิ่งด้วยความเร็วเดียวกันอีกครั้ง ที่ทำให้ฉันเชื่อว่าคอมไพเลอร์หรือ JIT จัดการเพื่อเพิ่มประสิทธิภาพการวนรอบเมื่อรู้ว่าprogressCheckคงที่