Saya baru mengenal java, dan menjalankan beberapa kode tadi malam, dan ini benar-benar mengganggu saya. Saya sedang membangun program sederhana untuk menampilkan setiap output X dalam loop untuk, dan saya melihat penurunan besar-besaran dalam kinerja, ketika saya menggunakan modulus sebagai variable % variable
vs variable % 5000
atau yang lainnya. Dapatkah seseorang menjelaskan kepada saya mengapa ini dan apa yang menyebabkannya? Jadi saya bisa lebih baik ...
Ini kode "efisien" (maaf jika saya salah sintaks, saya tidak ada di komputer dengan kode itu sekarang)
long startNum = 0;
long stopNum = 1000000000L;
for (long i = startNum; i <= stopNum; i++){
if (i % 50000 == 0) {
System.out.println(i);
}
}
Ini adalah "kode tidak efisien"
long startNum = 0;
long stopNum = 1000000000L;
long progressCheck = 50000;
for (long i = startNum; i <= stopNum; i++){
if (i % progressCheck == 0) {
System.out.println(i);
}
}
Pikiran Anda, saya punya variabel tanggal untuk mengukur perbedaan, dan setelah itu menjadi cukup lama, yang pertama mengambil 50 ms sementara yang lain mengambil 12 detik atau sesuatu seperti itu. Anda mungkin harus menambah stopNum
atau mengurangi progressCheck
jika PC Anda lebih efisien daripada milik saya atau tidak.
Saya mencari pertanyaan ini di web, tetapi saya tidak dapat menemukan jawaban, mungkin saya hanya tidak menanyakannya dengan benar.
EDIT: Saya tidak berharap pertanyaan saya begitu populer, saya menghargai semua jawaban. Saya melakukan benchmark pada setiap setengah waktu yang diambil, dan kode yang tidak efisien memakan waktu lebih lama, 1/4 detik vs 10 detik. Memang mereka menggunakan println, tetapi mereka berdua melakukan jumlah yang sama, jadi saya tidak akan membayangkan itu akan banyak condong, terutama karena perbedaannya berulang. Adapun jawabannya, karena saya baru di Jawa, saya akan membiarkan suara memutuskan untuk sekarang jawaban mana yang terbaik. Saya akan mencoba mengambilnya pada hari Rabu.
EDIT2: Saya akan membuat tes lain malam ini, di mana alih-alih modulus, itu hanya menambah variabel, dan ketika mencapai progressCheck, itu akan melakukan satu, dan kemudian mengatur ulang variabel itu ke 0. untuk opsi ke-3.
EDIT3.5:
Saya menggunakan kode ini, dan di bawah ini saya akan menunjukkan hasil saya .. Terima kasih SEMUA untuk bantuan yang luar biasa! Saya juga mencoba membandingkan nilai pendek dari panjang ke 0, jadi semua cek baru saya terjadi "65536" kali sehingga sama dengan pengulangan.
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");
}
}
Hasil:
- tetap = 874 ms (biasanya sekitar 1000 ms, tetapi lebih cepat karena kekuatannya 2)
- variabel = 8590 ms
- variabel akhir = 1944 ms (Apakah ~ 1000ms saat menggunakan 50.000)
- kenaikan = 1904 ms
- Konversi Pendek = 679 ms
Tidak cukup mengejutkan, karena kurangnya pembagian, Konversi Pendek 23% lebih cepat daripada cara "cepat". Ini menarik untuk dicatat. Jika Anda perlu menunjukkan atau membandingkan sesuatu setiap 256 kali (atau sekitar sana) Anda dapat melakukan ini, dan gunakan
if ((byte)integer == 0) {'Perform progress check code here'}
SATU FINAL MENARIK CATATAN, menggunakan modulus pada "Final menyatakan Variabel" dengan 65536 (bukan angka cantik) adalah setengah kecepatan (lebih lambat) dari nilai tetap. Di mana sebelumnya, benchmarking mendekati kecepatan yang sama.
final
di depanprogressCheck
variabel, keduanya berjalan pada kecepatan yang sama lagi. Itu membuat saya percaya bahwa kompiler atau JIT berhasil mengoptimalkan loop ketika ia tahu ituprogressCheck
konstan.