Ini adalah pertanyaan wawancara yang diajukan oleh manajer senior.
Mana yang lebih cepat?
while(1) {
// Some code
}
atau
while(2) {
//Some code
}
Saya mengatakan bahwa keduanya memiliki kecepatan eksekusi yang sama, karena ekspresi di dalam while
akhirnya harus dievaluasi true
atau false
. Dalam hal ini, keduanya mengevaluasi true
dan tidak ada instruksi bersyarat tambahan di dalam while
kondisi. Jadi, keduanya akan memiliki kecepatan eksekusi yang sama dan saya lebih suka saat (1).
Tetapi pewawancara berkata dengan percaya diri: "Periksa dasar-dasar Anda. Lebih while(1)
cepat daripada while(2)
." (Dia tidak menguji kepercayaan diri saya)
Apakah ini benar?
Lihat juga: Apakah "untuk (;;)" lebih cepat dari "sementara (BENAR)"? Jika tidak, mengapa orang menggunakannya?
c
performance
while-loop
Nikole
sumber
sumber
0x100000f90: jmp 0x100000f90
(alamat bervariasi, jelas) untuk kedua snippet. Pewawancara mungkin melakukan lindung nilai pada tes register vs lompatan sederhana yang ditandai. Kedua pertanyaan, dan anggapan mereka, lemah.Jawaban:
Kedua loop tidak terbatas, tetapi kita dapat melihat mana yang membutuhkan lebih banyak instruksi / sumber daya per iterasi.
Dengan menggunakan gcc, saya mengkompilasi dua program berikut untuk perakitan pada berbagai tingkat optimasi:
Bahkan tanpa optimasi (
-O0
), perakitan yang dihasilkan identik untuk kedua program . Oleh karena itu, tidak ada perbedaan kecepatan antara kedua loop.Untuk referensi, berikut adalah rakitan yang dihasilkan (menggunakan
gcc main.c -S -masm=intel
dengan bendera optimisasi):Dengan
-O0
:Dengan
-O1
:Dengan
-O2
dan-O3
(keluaran yang sama):Bahkan, rakitan yang dihasilkan untuk loop identik untuk setiap tingkat optimasi:
Bit-bit penting adalah:
Saya tidak bisa membaca perakitan dengan baik, tetapi ini jelas merupakan loop tanpa syarat. The
jmp
instruksi tanpa syarat me-reset program kembali ke.L2
label tanpa membandingkan nilai terhadap yang benar, dan tentu saja segera melakukannya lagi sampai program ini entah bagaimana berakhir. Ini berhubungan langsung dengan kode C / C ++:Edit:
Cukup menarik, bahkan tanpa optimasi , loop berikut semuanya menghasilkan output yang sama persis (tanpa syarat
jmp
) dalam perakitan:Dan bahkan keheranan saya:
Hal-hal menjadi sedikit lebih menarik dengan fungsi yang ditentukan pengguna:
Pada
-O0
, dua contoh ini benar-benar memanggilx
dan melakukan perbandingan untuk setiap iterasi.Contoh pertama (pengembalian 1):
Contoh kedua (kembali
sqrt(7)
):Namun, pada
-O1
dan di atas, mereka berdua menghasilkan rakitan yang sama seperti contoh sebelumnya (jmp
kembali tanpa syarat ke label sebelumnya).TL; DR
Di bawah GCC, loop yang berbeda dikompilasi ke rakitan yang sama. Kompiler mengevaluasi nilai-nilai konstan dan tidak repot melakukan perbandingan yang sebenarnya.
Moral dari cerita ini adalah:
sumber
-O
level.jmp
kembali ke awal atau menghapus loop sepenuhnya.break
pernyataan), tapi saya tetap mengujinya dan tidak, bahkan dengan kode di dalam loop, lompatannya adalah mutlak dan tanpa syarat untuk keduanyawhile(1)
danwhile(2)
. Jangan ragu untuk menguji yang lain sendiri jika Anda benar-benar khawatir.Ya,
while(1)
jauh lebih cepat daripadawhile(2)
, bagi manusia untuk membaca! Jika saya melihatwhile(1)
dalam basis kode yang tidak dikenal, saya segera tahu apa yang dimaksudkan oleh penulis, dan bola mata saya dapat melanjutkan ke baris berikutnya.Jika saya melihat
while(2)
, saya mungkin akan berhenti di jalur saya dan mencoba mencari tahu mengapa penulis tidak menuliswhile(1)
. Apakah jari penulis tergelincir pada keyboard? Apakah pengelola basis kode ini menggunakanwhile(n)
sebagai mekanisme komentar yang tidak jelas untuk membuat loop terlihat berbeda? Apakah ini solusi kasar untuk peringatan palsu di beberapa alat analisis statis yang rusak? Atau apakah ini petunjuk bahwa saya membaca kode yang dihasilkan? Apakah itu bug yang dihasilkan dari penemuan-dan-ganti-semua yang keliru, atau gabungan yang buruk, atau sinar kosmik? Mungkin baris kode ini seharusnya melakukan sesuatu yang sangat berbeda. Mungkin seharusnya membacawhile(w)
atauwhile(x2)
. Saya lebih baik menemukan penulis dalam sejarah file dan mengirimi mereka email "WTF" ... dan sekarang saya telah merusak konteks mental saya.while(2)
while(1)
akan mengambil sepersekian detik!Saya melebih-lebihkan, tetapi hanya sedikit. Keterbacaan kode sangat penting. Dan itu layak disebut dalam sebuah wawancara!
sumber
svn-annotate
ataugit blame
(atau apa pun) akan digunakan di sini, dan secara umum dibutuhkan beberapa menit untuk memuat riwayat menyalahkan file. Kemudian akhirnya memutuskan "ah saya mengerti, penulis menulis baris ini ketika baru keluar dari sekolah", baru saja kehilangan 10 menit ...1
.while(2)
dalam kode (turun untuk mempertimbangkan "Apakah pemelihara basis kode ini menggunakan sementara (n) sebagai mekanisme komentar yang tidak jelas untuk membuat loop terlihat berbeda?" ). Jadi tidak, Anda tidak melebih-lebihkan!Jawaban yang ada menunjukkan kode yang dihasilkan oleh kompiler tertentu untuk target tertentu dengan serangkaian opsi tertentu tidak sepenuhnya menjawab pertanyaan - kecuali pertanyaan itu diajukan dalam konteks tertentu ("Yang lebih cepat menggunakan gcc 4.7.2 untuk x86_64 dengan opsi default? ", misalnya).
Sejauh definisi bahasa yang bersangkutan, dalam mesin abstrak
while (1)
mengevaluasi konstanta integer1
, danwhile (2)
mengevaluasi konstanta integer2
; dalam kedua kasus hasilnya dibandingkan untuk kesetaraan ke nol. Standar bahasa tidak mengatakan apa-apa tentang kinerja relatif dari dua konstruksi.Saya dapat membayangkan bahwa kompiler yang sangat naif mungkin menghasilkan kode mesin yang berbeda untuk dua bentuk, setidaknya ketika dikompilasi tanpa meminta optimasi.
Di sisi lain, kompiler C mutlak harus mengevaluasi beberapa ekspresi konstan pada waktu kompilasi, ketika mereka muncul dalam konteks yang memerlukan ekspresi konstan. Sebagai contoh, ini:
membutuhkan diagnostik; sebuah compiler malas tidak memiliki opsi untuk menunda evaluasi
2+2
sampai waktu eksekusi. Karena kompiler harus memiliki kemampuan untuk mengevaluasi ekspresi konstan pada waktu kompilasi, tidak ada alasan yang baik untuk itu tidak memanfaatkan kemampuan itu bahkan ketika itu tidak diperlukan.Standar C ( N1570 6.8.5p4) mengatakan itu
Jadi, ekspresi konstan yang relevan adalah
1 == 0
dan2 == 0
, yang keduanya dievaluasiint
nilainya0
. (Perbandingan ini tersirat dalam semantikwhile
loop; mereka tidak ada sebagai ekspresi C aktual.)Kompiler yang terlalu naif dapat menghasilkan kode yang berbeda untuk kedua konstruksi. Misalnya, untuk yang pertama dapat menghasilkan loop tak terbatas tanpa syarat (memperlakukan
1
sebagai kasus khusus), dan untuk yang kedua dapat menghasilkan perbandingan run-time eksplisit setara dengan2 != 0
. Tetapi saya belum pernah menemukan kompiler C yang benar-benar akan berperilaku seperti itu, dan saya benar-benar ragu bahwa kompiler seperti itu ada.Kebanyakan kompiler (saya tergoda untuk mengatakan semua kompiler berkualitas produksi) memiliki opsi untuk meminta optimasi tambahan. Di bawah opsi seperti itu, bahkan lebih kecil kemungkinannya bahwa kompiler akan menghasilkan kode yang berbeda untuk dua bentuk.
Jika kompiler Anda membuat kode yang berbeda untuk kedua konstruk, pertama periksa apakah urutan kode yang berbeda benar-benar memiliki kinerja yang berbeda. Jika ya, coba kompilasi lagi dengan opsi optimisasi (jika tersedia). Jika masih berbeda, kirim laporan bug ke vendor kompiler. Ini bukan (tentu saja) bug dalam arti kegagalan untuk memenuhi standar C, tetapi hampir pasti masalah yang harus diperbaiki.
Intinya:
while (1)
danwhile(2)
hampir pasti memiliki kinerja yang sama. Mereka memiliki semantik yang sama persis, dan tidak ada alasan yang baik untuk kompiler untuk tidak menghasilkan kode yang sama.Dan meskipun kompiler sah untuk menghasilkan kode lebih cepat
while(1)
daripada untukwhile(2)
, kompilator sama legalnya untuk menghasilkan kode lebih cepatwhile(1)
daripada untuk kejadian lainwhile(1)
dalam program yang sama.(Ada pertanyaan lain yang tersirat dalam pertanyaan yang Anda ajukan: Bagaimana Anda berurusan dengan pewawancara yang bersikeras pada poin teknis yang salah. Itu mungkin akan menjadi pertanyaan yang bagus untuk situs Workplace ).
sumber
while
harus dari tipe skalar dan loop body diulangi sampai ekspresi sebanding dengan 0. Ia tidak mengatakan bahwa ada implisitexpr != 0
yang dievaluasi ... yang akan memerlukan hasil dari itu - 0 atau 1 - pada gilirannya dibandingkan dengan 0, tak terhingga. Tidak, ekspresi dibandingkan dengan 0, tetapi perbandingan itu tidak menghasilkan nilai. PS saya terbalik.<expr> == 0
; itulah yang "membandingkan sama dengan 0" berarti dalam C. Perbandingan itu adalah bagian dari semantikwhile
loop. Tidak ada implikasi, baik dalam standar atau dalam jawaban saya, bahwa hasilnya perlu dibandingkan0
lagi. (Seharusnya saya menulis==
daripada!=
.) Tetapi bagian dari jawaban saya tidak jelas, dan saya akan memperbaruinya.while (2)
,while (pointer)
,while (9.67)
, oleh yang paling naif, compiler unoptimized, Anda tidak akan melihat kode yang dihasilkan bahwa hasil0
atau1
. "Aku seharusnya menulis == daripada! =" - tidak, itu tidak masuk akal.... == 0
ekspresi C. Maksud saya adalah bahwa kedua "membandingkan sama dengan 0" yang diperlukan oleh deskripsi standar tentangwhile
loop danx == 0
ekspresi eksplisit secara logis menyiratkan operasi yang sama. Dan saya berpikir bahwa kompiler C naif yang menyakitkan dapat menghasilkan kode yang menghasilkanint
nilai0
atau1
untuk setiapwhile
loop - meskipun saya tidak percaya ada kompiler yang sebenarnya sangat naif.Tunggu sebentar. Pewawancara, apakah dia terlihat seperti orang ini?
Sudah cukup buruk bahwa pewawancara sendiri telah gagal dalam wawancara ini, bagaimana jika programmer lain di perusahaan ini telah "lulus" tes ini?
Tidak. Mengevaluasi pernyataan
1 == 0
dan2 == 0
harus sama cepatnya. Kita bisa membayangkan implementasi kompiler yang buruk di mana satu mungkin lebih cepat dari yang lain. Tapi tidak ada yang baik alasan mengapa salah satu harus lebih cepat dari yang lain.Bahkan jika ada beberapa keadaan yang tidak jelas ketika klaim itu benar, programmer tidak boleh dievaluasi berdasarkan pengetahuan hal-hal yang tidak jelas (dan dalam hal ini, menyeramkan). Jangan khawatir tentang wawancara ini, langkah terbaik di sini adalah pergi.
Penafian: Ini BUKAN kartun Dilbert asli. Ini hanyalah sebuah mashup .
sumber
cmp
operan berjalan dalam siklus kurang membandingkan 1 ke 0 dari 2 ke 0? berapa banyak siklus yang diperlukan untuk menjalankan cmp secara umum? apakah itu variabel menurut pola bit? Apakah mereka lebih sedikit "kompleks" pola bit yang melambatcmp
? Saya tidak tahu secara pribadi. Anda bisa membayangkan implementasi super idiot yang memeriksa sedikit demi sedikit dari peringkat 0 hingga n (misalnya n = 31).cmp
operan harus sama cepat untuk 1 dan 200. Mungkin kita bisa membayangkan implementasi bodoh di mana ini tidak terjadi. Tapi bisakah kita membayangkan implementasi non-idiot di manawhile(1)
lebih cepat dari ituwhile(200)
? Demikian pula, jika di zaman prasejarah, satu-satunya implementasi yang tersedia adalah idiot seperti itu, haruskah kita meributkannya hari ini? Saya tidak berpikir begitu, ini adalah pembicaraan bos berambut runcing, dan permata yang nyata pada saat itu!Penjelasan Anda benar. Ini tampaknya menjadi pertanyaan yang menguji kepercayaan diri Anda di samping pengetahuan teknis.
Omong-omong, jika Anda menjawab
pewawancara akan berkata
Jadi dengan menjawab seperti yang Anda lakukan, Anda menghemat waktu yang seharusnya tidak Anda buang untuk membahas pertanyaan buruk ini.
Berikut adalah contoh kode yang dihasilkan oleh kompiler di sistem saya (MS Visual Studio 2012), dengan optimisasi dimatikan:
Dengan optimisasi dihidupkan:
Jadi kode yang dihasilkan persis sama, setidaknya dengan kompiler yang mengoptimalkan.
sumber
while
lama mendahuluinya) dan operanwhile
bukan dari boolean atau _Bool atau tipe spesifik lainnya. Operandwhile
dapat berupa ekspresi apa saja ... saat break pada 0 dan berlanjut pada non-0.while (00000001) {}
menjadiwhile (00000000) {}
. Semakin banyak bit yang benar, semakin kecil peluang nilai tersebut berubah menjadi false. Sayangnya, 2 juga hanya memiliki satu bit yang benar. 3, bagaimanapun, akan berjalan secara signifikan lebih lama. Ini juga hanya berlaku untuk kompiler yang tidak selalu mengoptimalkan ini (VC ++).Penjelasan yang paling mungkin untuk pertanyaan tersebut adalah bahwa pewawancara berpikir bahwa prosesor memeriksa bit individual dari angka-angka, satu per satu, sampai menyentuh nilai yang tidak nol:
Jika "nol?" Algoritma dimulai dari sisi kanan nomor dan harus memeriksa setiap bit sampai mencapai bit non-nol,
while(1) { }
loop harus memeriksa dua kali lebih banyak bit per iterasi sebagaiwhile(2) { }
loop.Ini membutuhkan model mental yang sangat salah tentang bagaimana komputer bekerja, tetapi ia memang memiliki logika internalnya sendiri. Salah satu cara untuk memeriksa adalah dengan menanyakan apakah
while(-1) { }
atauwhile(3) { }
akan sama cepatnya, atau apakahwhile(32) { }
akan lebih lambat .sumber
cmp
algoritma dari CPU adalah pemeriksaan bit linier dengan keluar loop awal pada perbedaan pertama.-O0
output gcc atau dentang tidak cukup literal." Saya tidak pernah mengatakan hal seperti itu dan saya tidak memikirkan gcc atau dentang sama sekali. Anda pasti salah baca saya. Saya hanya tidak sependapat dengan Anda bahwa apa yang dihasilkan MSVC itu lucu.while(1)
tidak merusak sebelum loop, tetapi pada ekspresi. Tapi itu masih runtuh di dalam loop ketika mengoptimalkan ekspresi. Ambil kode ini dengan banyak istirahat. Dalam mode debugging yang tidak dioptimalkan Anda mendapatkan ini . Saat mengoptimalkan, banyak breakpoint jatuh bersama-sama atau bahkan tumpah ke fungsi berikutnya (IDE menunjukkan breakpoint hasil saat debugging) - pembongkaran yang sesuai .Tentu saja saya tidak tahu maksud sebenarnya dari manajer ini, tetapi saya mengusulkan pandangan yang sama sekali berbeda: Ketika merekrut anggota baru ke dalam tim, akan berguna untuk mengetahui bagaimana dia bereaksi terhadap situasi konflik.
Mereka mendorong Anda ke dalam konflik. Jika ini benar, mereka pintar dan pertanyaannya bagus. Untuk beberapa industri, seperti perbankan, memposting masalah Anda ke Stack Overflow bisa menjadi alasan penolakan.
Tapi tentu saja saya tidak tahu, saya hanya mengusulkan satu opsi.
sumber
Saya pikir petunjuknya dapat ditemukan di "diminta oleh manajer senior". Orang ini jelas berhenti pemrograman ketika ia menjadi manajer dan kemudian butuh beberapa tahun untuk menjadi manajer senior. Tidak pernah kehilangan minat dalam pemrograman, tetapi tidak pernah menulis baris sejak saat itu. Jadi rujukannya bukanlah "kompiler yang layak di luar sana" seperti beberapa jawaban menyebutkan, tetapi "kompiler yang digunakan orang ini 20-30 tahun yang lalu".
Pada saat itu, programmer menghabiskan banyak waktu mereka untuk mencoba berbagai metode untuk membuat kode mereka lebih cepat dan lebih efisien karena waktu CPU dari 'komputer mini sentral' sangat berharga. Seperti yang dilakukan orang menulis kompiler. Saya menduga bahwa satu-satunya kompiler yang disediakan perusahaannya pada waktu itu dioptimalkan berdasarkan 'pernyataan yang sering ditemui yang dapat dioptimalkan' dan mengambil sedikit jalan pintas ketika bertemu beberapa saat (1) dan mengevaluasi semuanya lain, termasuk beberapa saat (2). Memiliki pengalaman seperti itu dapat menjelaskan posisi dan kepercayaan dirinya terhadapnya.
Pendekatan terbaik untuk mempekerjakan Anda mungkin adalah pendekatan yang memungkinkan manajer senior terbawa suasana dan memberi kuliah Anda 2-3 menit tentang "hari-hari baik pemrograman" sebelum ANDA dengan lancar membawanya ke subjek wawancara berikutnya. (Pengaturan waktu yang baik penting di sini - terlalu cepat dan Anda menginterupsi ceritanya - terlalu lambat dan Anda dicap sebagai orang yang kurang fokus). Katakan padanya di akhir wawancara bahwa Anda akan sangat tertarik untuk mempelajari lebih lanjut tentang topik ini.
sumber
Anda seharusnya bertanya kepadanya bagaimana dia mencapai kesimpulan itu. Di bawah setiap kompiler yang layak di luar sana, keduanya mengkompilasi dengan instruksi asm yang sama. Jadi, dia seharusnya memberi tahu Anda kompiler untuk memulai. Dan meskipun demikian, Anda harus mengetahui kompiler dan platform dengan sangat baik untuk membuat tebakan teoritis. Dan pada akhirnya, itu tidak terlalu penting dalam praktik, karena ada faktor-faktor eksternal lainnya seperti fragmentasi memori atau beban sistem yang akan mempengaruhi loop lebih dari detail ini.
sumber
Demi pertanyaan ini, saya harus menambahkan bahwa saya ingat Doug Gwyn dari Komite C menulis bahwa beberapa kompiler C awal tanpa pass pengoptimal akan menghasilkan tes dalam perakitan untuk
while(1)
(dibandingkan denganfor(;;)
yang tidak memilikinya).Saya akan menjawab kepada pewawancara dengan memberikan catatan sejarah ini dan kemudian mengatakan bahwa bahkan jika saya akan sangat terkejut setiap kompiler melakukan ini, kompiler dapat memiliki:
while(1)
danwhile(2)
while(1)
karena mereka dianggap sebagai idiomatik. Ini akan meninggalkanwhile(2)
dengan tes dan karenanya membuat perbedaan kinerja antara keduanya.Saya tentu saja akan menambahkan kepada pewawancara yang tidak mempertimbangkan
while(1)
danwhile(2)
membangun yang sama adalah tanda optimasi berkualitas rendah karena ini adalah konstruksi yang setara.sumber
Cara lain untuk pertanyaan seperti itu adalah untuk melihat apakah Anda punya keberanian untuk memberi tahu manajer Anda bahwa dia salah! Dan seberapa lembut Anda bisa mengomunikasikannya.
Insting pertama saya adalah menghasilkan output perakitan untuk menunjukkan kepada manajer bahwa setiap kompiler yang layak harus mengatasinya, dan jika tidak melakukannya, Anda akan mengirimkan tambalan berikutnya untuk itu :)
sumber
Untuk melihat begitu banyak orang mempelajari masalah ini, perlihatkan dengan tepat mengapa ini bisa menjadi ujian untuk melihat seberapa cepat Anda ingin mengoptimalkan berbagai hal secara mikro .
Jawaban saya adalah; tidak masalah, saya lebih fokus pada masalah bisnis yang sedang kita selesaikan. Bagaimanapun, itulah yang akan saya bayar.
Selain itu, saya akan memilih
while(1) {}
karena itu lebih umum, dan rekan satu tim lainnya tidak perlu menghabiskan waktu untuk mencari tahu mengapa seseorang memilih angka yang lebih tinggi dari 1.Sekarang, tulis beberapa kode. ;-)
sumber
Jika Anda begitu khawatir tentang pengoptimalan, Anda harus menggunakannya
karena itu tidak memiliki tes. (mode sinis)
sumber
while(2)
, ia meninggalkan ruang untuk optimasi, maka Anda cukup beralih kefor (;;)
ketika Anda siap untuk meningkatkan kinerja.Menurut saya ini adalah salah satu pertanyaan wawancara perilaku yang disamarkan sebagai pertanyaan teknis. Beberapa perusahaan melakukan ini - mereka akan mengajukan pertanyaan teknis yang seharusnya cukup mudah dijawab oleh programmer mana pun yang kompeten, tetapi ketika orang yang diwawancarai memberikan jawaban yang benar, pewawancara akan memberi tahu mereka bahwa mereka salah.
Perusahaan ingin melihat bagaimana Anda akan bereaksi dalam situasi ini. Apakah Anda duduk di sana dengan tenang dan tidak memaksakan jawaban Anda benar, karena keraguan diri atau takut mengganggu pewawancara? Atau apakah Anda bersedia menantang seseorang yang memiliki otoritas yang Anda tahu salah? Mereka ingin melihat apakah Anda bersedia membela keyakinan Anda, dan jika Anda bisa melakukannya dengan cara yang bijaksana dan penuh hormat.
sumber
Saya dulu memprogram kode C dan Majelis kembali ketika omong kosong semacam ini mungkin membuat perbedaan. Ketika hal itu membuat perbedaan, kami menulisnya di Majelis.
Jika saya ditanya pertanyaan itu, saya akan mengulangi kutipan terkenal Donald Knuth tahun 1974 tentang pengoptimalan prematur dan berjalan jika pewawancara tidak tertawa dan melanjutkan.
sumber
Mungkin pewawancara mengajukan pertanyaan bodoh seperti itu dengan sengaja dan ingin Anda membuat 3 poin:
sumber
Inilah masalahnya: Jika Anda benar-benar menulis sebuah program dan mengukur kecepatannya, kecepatan kedua loop bisa berbeda! Untuk perbandingan yang masuk akal:
dengan beberapa kode ditambahkan yang mencetak waktu, beberapa efek acak seperti bagaimana loop diposisikan dalam satu atau dua baris cache dapat membuat perbedaan. Satu loop mungkin kebetulan sepenuhnya dalam satu baris cache, atau pada awal baris cache, atau mungkin untuk mengangkangi dua baris cache. Dan sebagai hasilnya, apa pun yang diklaim pewawancara paling cepat mungkin sebenarnya tercepat - secara kebetulan.
Skenario kasus terburuk: Kompilator pengoptimal tidak mengetahui apa yang dilakukan loop, tetapi memperkirakan bahwa nilai yang dihasilkan saat loop kedua dieksekusi adalah yang sama dengan yang dihasilkan oleh yang pertama. Dan menghasilkan kode lengkap untuk loop pertama, tetapi tidak untuk yang kedua.
sumber
Keduanya sama - sama.
Menurut spesifikasi apa pun yang bukan 0 dianggap benar, bahkan tanpa optimasi apa pun, dan kompiler yang baik tidak akan menghasilkan kode apa pun untuk sementara (1) atau sementara (2). Kompiler akan menghasilkan pemeriksaan sederhana untuk
!= 0
.sumber
Menilai dari jumlah waktu dan upaya yang dihabiskan orang untuk menguji, membuktikan, dan menjawab pertanyaan yang sangat langsung ini, saya mengatakan bahwa keduanya dibuat sangat lambat dengan mengajukan pertanyaan.
Dan untuk menghabiskan lebih banyak waktu untuk itu ...
"Sementara (2)" konyol, karena,
"while (1)", dan "while (true)" secara historis digunakan untuk membuat loop tak terbatas yang mengharapkan "break" untuk dipanggil pada beberapa tahap di dalam loop berdasarkan kondisi yang pasti akan terjadi.
"1" hanya ada di sana untuk selalu mengevaluasi ke benar dan karena itu, untuk mengatakan "sementara (2)" sama konyolnya dengan mengatakan "sementara (1 + 1 == 2)" yang juga akan mengevaluasi ke benar.
Dan jika Anda ingin benar-benar konyol, gunakan saja: -
Saya ingin berpikir bahwa pembuat kode Anda membuat kesalahan ketik yang tidak mempengaruhi jalannya kode, tetapi jika dia sengaja menggunakan "2" hanya untuk menjadi aneh, maka pindahkan dia sebelum dia memasukkan semua file Anda ke kode Anda sehingga sulit untuk baca dan bekerja dengan.
sumber
Itu tergantung pada kompiler.
Jika mengoptimalkan kode, atau jika mengevaluasi 1 dan 2 menjadi benar dengan jumlah instruksi yang sama untuk set instruksi tertentu, kecepatan eksekusi akan sama.
Dalam kasus nyata itu akan selalu sama cepatnya, tetapi akan mungkin untuk membayangkan kompiler tertentu dan sistem tertentu ketika ini akan dievaluasi secara berbeda.
Maksud saya: ini bukan pertanyaan terkait bahasa (C).
sumber
Karena orang yang ingin menjawab pertanyaan ini menginginkan loop tercepat, saya akan menjawab bahwa keduanya sama-sama menyusun kode perakitan yang sama, seperti yang dinyatakan dalam jawaban lain. Namun demikian Anda dapat menyarankan kepada pewawancara menggunakan 'loop membuka gulungan'; a do {} while bukan loop while.
Hati-hati: Anda perlu memastikan bahwa loop setidaknya akan selalu berjalan sekali .
Lingkaran harus memiliki kondisi istirahat di dalamnya.
Juga untuk loop semacam itu, saya pribadi lebih suka menggunakan do {} while (42) karena bilangan bulat apa pun, kecuali 0, akan melakukan pekerjaan itu.
sumber
Jawaban yang jelas adalah: seperti yang diposting, kedua fragmen akan menjalankan loop infinite yang sama sibuknya, yang membuat program menjadi sangat lambat .
Meskipun mendefinisikan ulang kata kunci C sebagai makro secara teknis akan memiliki perilaku yang tidak terdefinisi, itu adalah satu-satunya cara yang dapat saya pikirkan untuk membuat salah satu kode fragmen dengan cepat: Anda dapat menambahkan baris ini di atas 2 fragmen:
memang akan membuat
while(1)
dua kali lebih cepat (atau setengah lambat)while(2)
.sumber
Satu-satunya alasan saya bisa memikirkan mengapa hal
while(2)
itu menjadi lebih lambat adalah:Kode mengoptimalkan perulangan ke
cmp eax, 2
Ketika pengurangan terjadi, Anda pada dasarnya mengurangi
Sebuah.
00000000 - 00000010 cmp eax, 2
dari pada
b.
00000000 - 00000001 cmp eax, 1
cmp
hanya mengeset flag dan tidak menetapkan hasilnya. Jadi pada bit paling signifikan kita tahu apakah kita perlu meminjam atau tidak dengan b . Sedangkan dengan sebuah Anda harus melakukan dua subtractions sebelum Anda mendapatkan meminjam a.sumber