Jika Anda harus mengulang melalui loop sebanyak 7 kali, apakah Anda akan menggunakan:
for (int i = 0; i < 7; i++)
atau:
for (int i = 0; i <= 6; i++)
Ada dua pertimbangan:
- kinerja
- keterbacaan
Untuk kinerja saya mengasumsikan Java atau C #. Apakah penting jika "kurang dari" atau "kurang dari atau sama dengan" digunakan? Jika Anda memiliki wawasan untuk bahasa yang berbeda, harap tunjukkan mana.
Untuk keterbacaan, saya mengasumsikan array berbasis 0.
UPD: Penyebutan saya tentang array berbasis 0 mungkin membingungkan. Saya tidak berbicara tentang iterasi melalui elemen array. Hanya lingkaran umum.
Ada poin bagus di bawah ini tentang menggunakan konstanta yang akan menjelaskan apa angka ajaib ini. Jadi jika saya " int NUMBER_OF_THINGS = 7
" maka " i <= NUMBER_OF_THINGS - 1
" akan terlihat aneh, bukan.
performance
conventions
readability
Eugene Katz
sumber
sumber
Jawaban:
Yang pertama lebih idiomatis . Secara khusus, ini menunjukkan (dalam arti berbasis 0) jumlah iterasi. Saat menggunakan sesuatu berbasis 1 (misalnya JDBC, IIRC) saya mungkin tergoda untuk menggunakan <=. Begitu:
Saya berharap perbedaan kinerja menjadi tidak signifikan dalam kode dunia nyata.
sumber
Kedua loop tersebut berulang sebanyak 7 kali. Saya akan mengatakan yang satu dengan 7 di dalamnya lebih mudah dibaca / lebih jelas, kecuali Anda memiliki alasan yang benar-benar bagus untuk yang lain.
sumber
Saya ingat dari hari-hari saya ketika kami melakukan Majelis 8086 di kampus, itu lebih baik dilakukan:
karena ada operasi JNS yang berarti Langsung jika Tidak Ada Tanda. Menggunakan ini berarti bahwa tidak ada pencarian memori setelah setiap siklus untuk mendapatkan nilai perbandingan dan tidak ada perbandingan. Saat ini sebagian besar kompiler mengoptimalkan penggunaan register sehingga hal memori tidak lagi penting, tetapi Anda masih mendapatkan perbandingan yang tidak diperlukan.
By the way menempatkan 7 atau 6 di lingkaran Anda memperkenalkan " angka ajaib ". Untuk keterbacaan yang lebih baik, Anda harus menggunakan konstanta dengan Nama Pengungkapan Intent. Seperti ini:
EDIT: Orang-orang tidak mendapatkan hal perakitan sehingga jelas diperlukan contoh yang lebih lengkap:
Jika kita lakukan untuk (i = 0; i <= 10; i ++) Anda perlu melakukan ini:
Jika kita lakukan untuk (int i = 10; i> -1; i--) maka Anda bisa lolos dengan ini:
Saya baru saja memeriksa dan kompiler C ++ Microsoft tidak melakukan optimasi ini, tetapi ia melakukannya jika Anda melakukannya:
Jadi moralnya adalah jika Anda menggunakan Microsoft C ++ †, dan naik atau turun tidak ada bedanya, untuk mendapatkan perulangan cepat Anda harus menggunakan:
daripada salah satu dari ini:
Tapi terus terang mendapatkan keterbacaan "untuk (int i = 0; i <= 10; i ++)" biasanya jauh lebih penting daripada melewatkan satu perintah prosesor.
† Kompiler lain dapat melakukan hal yang berbeda.
sumber
7-i
yang akan membanjiri optimasi yang Anda dapatkan dari menghitung mundur.Saya selalu menggunakan <array.length karena lebih mudah dibaca daripada <= array.length-1.
juga memiliki <7 dan mengingat bahwa Anda tahu itu dimulai dengan indeks 0 itu harus intuitif bahwa angka adalah jumlah iterasi.
sumber
Dilihat dari sudut pandang optimalisasi, itu tidak masalah.
Dilihat dari sudut pandang gaya kode saya lebih suka <. Alasan:
jauh lebih mudah dibaca daripada
juga <memberi Anda jumlah iterasi langsung.
Pilihan lain untuk <adalah bahwa Anda dapat mencegah banyak kesalahan tidak disengaja satu demi satu.
sumber
@ Chris, Pernyataan Anda tentang. Panjang menjadi mahal di. NET sebenarnya tidak benar dan dalam kasus tipe sederhana kebalikannya.
sebenarnya lebih lambat dari
Nanti adalah kasus yang dioptimalkan oleh runtime. Karena runtime dapat menjamin saya adalah indeks yang valid ke dalam array tidak ada pemeriksaan batas yang dilakukan. Dalam yang pertama, runtime tidak dapat menjamin bahwa saya tidak dimodifikasi sebelum loop dan memaksa batas memeriksa pada array untuk setiap pencarian indeks.
sumber
.lenght
OR.size
. Saya tidak yakin tetapi dan tidak percaya diri tetapi ingin memastikan saja.Itu tidak membuat perbedaan yang efektif dalam hal kinerja. Karena itu saya akan menggunakan mana yang lebih mudah untuk dipahami dalam konteks masalah yang Anda pecahkan.
sumber
Saya lebih memilih:
Saya pikir itu lebih mudah diterjemahkan menjadi "iterasi melalui loop 7 kali".
Saya tidak yakin tentang implikasi kinerja - saya menduga ada perbedaan yang bisa dikompilasi.
sumber
Di Java 1.5 Anda bisa melakukannya
jadi untuk kasus array Anda tidak perlu khawatir.
sumber
Saya tidak berpikir ada perbedaan kinerja. Bentuk kedua jelas lebih mudah dibaca, Anda tidak perlu mengurangi secara mental untuk menemukan nomor iterasi terakhir.
EDIT: Saya melihat orang lain tidak setuju. Bagi saya pribadi, saya suka melihat angka indeks aktual dalam struktur loop. Mungkin karena ini lebih mengingatkan pada
0..6
sintaksis Perl , yang saya tahu setara dengan(0,1,2,3,4,5,6)
. Jika saya melihat angka 7, saya harus memeriksa operator di sebelahnya untuk melihat bahwa, pada kenyataannya, indeks 7 tidak pernah tercapai.sumber
Saya akan mengatakan menggunakan versi "<7" karena itulah yang akan dibaca oleh sebagian besar orang - jadi jika orang membaca skim Anda dengan cepat, mereka mungkin menafsirkannya dengan salah.
Saya tidak akan khawatir tentang apakah "<" lebih cepat dari "<=", cukup dibaca.
Jika Anda ingin meningkatkan kecepatan, pertimbangkan hal berikut:
Untuk meningkatkan kinerja, Anda dapat mengaturnya kembali menjadi:
Perhatikan penghapusan GetCount () dari loop (karena itu akan ditanyai dalam setiap loop) dan perubahan "i ++" menjadi "++ i".
sumber
Dalam C ++, saya lebih suka menggunakan
!=
, yang dapat digunakan dengan semua wadah STL. Tidak semua iterator wadah STL kurang sebanding.sumber
Edsger Dijkstra menulis sebuah artikel tentang ini pada tahun 1982 di mana ia berpendapat untuk yang lebih rendah <= i <atas:
sumber
Pertama, jangan gunakan 6 atau 7.
Lebih baik digunakan:
Dalam hal ini lebih baik daripada menggunakan
Bahkan lebih baik (Java / C #):
Dan bahkan lebih baik (C #)
Loop terbalik memang lebih cepat tetapi karena lebih sulit untuk dibaca (jika tidak oleh Anda oleh programmer lain), lebih baik untuk menghindari. Terutama di C #, Java ...
sumber
Saya setuju dengan kerumunan yang mengatakan bahwa 7 masuk akal dalam kasus ini, tetapi saya akan menambahkan bahwa dalam kasus di mana 6 penting, katakan Anda ingin menjelaskan Anda hanya bertindak pada objek hingga indeks 6, maka <= Lebih baik karena membuat 6 lebih mudah dilihat.
sumber
Kembali ke perguruan tinggi, saya ingat sesuatu tentang dua operasi ini menjadi serupa dalam waktu komputasi pada CPU. Tentu saja, kita berbicara di tingkat perakitan.
Namun, jika Anda berbicara C # atau Java, saya benar-benar tidak berpikir satu akan menjadi penambah kecepatan dari yang lain, Beberapa nanodetik yang Anda peroleh kemungkinan besar tidak sebanding dengan kebingungan yang Anda perkenalkan.
Secara pribadi, saya akan menulis kode yang masuk akal dari sudut pandang implementasi bisnis, dan memastikannya mudah dibaca.
sumber
Ini jatuh langsung di bawah kategori "Membuat Kode yang Salah Terlihat Salah" .
Dalam bahasa pengindeksan berbasis nol, seperti Java atau C # orang terbiasa dengan variasi pada
index < count
kondisi. Dengan demikian, meningkatkan konvensi defacto ini akan membuat kesalahan satu per satu lebih jelas.Mengenai kinerja: setiap kompiler bagus yang bernilai jejak kakinya harus di-render seperti non-isu.
sumber
Sebagai sedikit samping, ketika perulangan melalui array atau koleksi lainnya di. Net, saya menemukan
agar lebih mudah dibaca daripada angka untuk loop. Ini tentu saja mengasumsikan bahwa penghitung Int yang sebenarnya itu sendiri tidak digunakan dalam kode loop. Saya tidak tahu apakah ada perubahan kinerja.
sumber
Ada banyak alasan bagus untuk menulis i <7. Memiliki angka 7 dalam satu lingkaran yang berulang 7 kali adalah baik. Performanya identik secara efektif. Hampir semua orang menulis i <7. Jika Anda menulis agar mudah dibaca, gunakan formulir yang semua orang akan langsung kenal.
sumber
Saya selalu lebih suka:
sumber
Membuat kebiasaan menggunakan <akan membuatnya konsisten untuk Anda dan pembaca ketika Anda mengulangi melalui array. Akan lebih mudah bagi semua orang untuk memiliki konvensi standar. Dan jika Anda menggunakan bahasa dengan array berbasis 0, maka <adalah konvensi.
Ini hampir pasti lebih penting daripada perbedaan kinerja apa pun antara <dan <=. Bertujuan untuk fungsionalitas dan keterbacaan pertama, lalu optimalkan.
Catatan lain adalah bahwa akan lebih baik dalam kebiasaan melakukan ++ i daripada i ++, karena mengambil dan menambah membutuhkan sementara dan peningkatan dan pengambilan tidak. Untuk bilangan bulat, kompiler Anda mungkin akan mengoptimalkan sementara pergi, tetapi jika jenis iterasi Anda lebih kompleks, itu mungkin tidak bisa.
sumber
Jangan gunakan angka ajaib.
Kenapa 7? (atau 6 dalam hal ini).
gunakan simbol yang benar untuk nomor yang ingin Anda gunakan ...
Dalam hal ini saya pikir lebih baik digunakan
sumber
Operator '<' dan '<=' persis dengan biaya kinerja yang sama.
Operator '<' adalah standar dan lebih mudah dibaca dalam loop berbasis nol.
Menggunakan ++ i bukannya i ++ meningkatkan kinerja di C ++, tetapi tidak di C # - Saya tidak tahu tentang Java.
sumber
Seperti yang telah diamati orang, tidak ada perbedaan dalam salah satu dari dua alternatif yang Anda sebutkan. Hanya untuk mengonfirmasi ini, saya melakukan pembandingan sederhana dalam JavaScript.
Anda dapat melihat hasilnya di sini . Apa yang tidak jelas dari ini adalah bahwa jika saya menukar posisi tes 1 dan 2, hasil untuk 2 tes tersebut ditukar, ini jelas merupakan masalah memori. Namun tes ke-3, tes di mana saya membalikkan urutan iterasi jelas lebih cepat.
sumber
Seperti yang dikatakan semua orang, sudah biasa menggunakan iterator yang diindeks 0 bahkan untuk hal-hal di luar array. Jika semuanya dimulai pada
0
dan berakhir padan-1
, dan batas bawah selalu<=
dan batas atas selalu<
, ada jauh lebih sedikit pemikiran yang harus Anda lakukan ketika meninjau kode.sumber
Pertanyaan yang bagus Jawaban saya: gunakan tipe A ('<')
i < strlen(s)
daripada indeks elemen terakhir sehingga keseragaman itu penting.Masalah lain adalah dengan keseluruhan konstruksi ini.
i
muncul 3 kali di dalamnya, sehingga dapat salah ketik. Konstruk for-loop mengatakan cara melakukan alih - alih apa yang harus dilakukan . Saya sarankan mengadopsi ini:BOOST_FOREACH(i, IntegerInterval(0,7))
Ini lebih jelas, mengkompilasi untuk memberikan instruksi asm yang sama, dll. Tanyakan saya kode IntegerInterval jika Anda suka.
sumber
Begitu banyak jawaban ... tapi saya yakin saya punya sesuatu untuk ditambahkan.
Preferensi saya adalah angka-angka literal untuk dengan jelas menunjukkan nilai apa yang akan saya ambil dalam loop . Jadi dalam kasus iterasi melalui array berbasis nol:
for (int i = 0; i <= array.Length - 1; ++i)
Dan jika Anda hanya mengulang, tidak mengulangi melalui array, menghitung dari 1 hingga 7 cukup intuitif:
for (int i = 1; i <= 7; ++i)
Keterbacaan meningkatkan kinerja hingga Anda memprofilkannya, karena Anda mungkin tidak tahu apa yang akan dilakukan oleh kompiler atau runtime dengan kode Anda sampai saat itu.
sumber
Anda juga bisa menggunakannya
!=
. Dengan cara itu, Anda akan mendapatkan infinite loop jika Anda membuat kesalahan dalam inisialisasi, menyebabkan kesalahan diketahui sebelumnya dan masalah apa pun yang menyebabkannya dibatasi terjebak dalam loop (daripada memiliki masalah jauh kemudian dan tidak menemukan Itu).sumber
Saya pikir baik-baik saja, tetapi ketika Anda telah memilih, tetap berpegang pada satu atau yang lain. Jika Anda terbiasa menggunakan <=, maka cobalah untuk tidak menggunakan <dan sebaliknya.
Saya lebih suka <=, tetapi dalam situasi di mana Anda bekerja dengan indeks yang dimulai dari nol, saya mungkin akan mencoba dan menggunakan <. Tapi itu semua preferensi pribadi.
sumber
Dari sudut pandang logis, Anda harus berpikir itu
< count
akan lebih efisien daripada<= count
untuk alasan yang tepat yang<=
akan menguji kesetaraan juga.sumber