Jeffrey Cross
Jeffrey Cross

Peranti Duff: gelung membuka untuk bahasa yang ditafsirkan

Pada tahun 1983, Tom Duff mencipta cara yang sangat pelik untuk menggunakan suis dan pernyataan kes bahasa C untuk kod "mengosongkan" pengoptimuman gelung besar. Sebagai contoh, beliau menyifatkan gelung mudah yang menyalin pelbagai ke senarai output:

hantar (kepada, dari, mengira) mendaftar pendek * kepada, * dari; daftar bilangan; {do * to = * from ++; sementara (- count> 0); }

Pada setiap lelaran gelung, sebagai tambahan kepada salinan yang sedang dilakukan, pembolehubah kiraan diturunkan dan perbandingan dilakukan terhadap 0. Peranti Duff membolehkan anda mencapai hasil yang sama, tetapi dengan hanya 8 ke atas:

hantar (kepada, dari, mengira) mendaftar pendek * kepada, * dari; daftar bilangan; {register n = (count + 7) / 8; suis (mengira% 8) {kes 0: lakukan {* to = * daripada ++; kes 7: * to = * dari ++; kes 6: * to = * dari ++; kes 5: * to = * dari ++; kes 4: * to = * dari ++; kes 3: * to = * dari ++; kes 2: * to = * dari ++; kes 1: * to = * dari ++; } sementara (- n> 0); }}

Apa yang berlaku ialah gelung itu dibuka 8 kali, jadi setiap lelaran gelung mengendalikan kod dalaman 8 kali tanpa perbandingan. The genius of Duff's Device adalah bahawa ia mengambil keuntungan dari cara kerja switch / struktur C. Kali pertama melalui, jika lelaran tidak dibahagikan secara sama rata dengan 8, kod gelung dilaksanakan cukup masa untuk menyamai sisihan lelaran / 8.Ini agak pelik, kerana kenyataan "lakukan" berlaku dalam suis, tetapi terdapat pernyataan "kes" dalam "lakukan". Walau bagaimanapun, ia sah C.

Sebelum seseorang bersorak, ingatlah bahawa ini hanya sesuai untuk mempercepatkan prestasi gelung dalaman apabila tiada algoritma yang lebih baik dan sesuai. Sekiranya anda kod C, pengkompil yang paling moden cukup pintar untuk mengoptimumkan kod anda secara automatik dan melepaskan gelung untuk anda.

Untuk bahasa yang difahami seperti PHP atau Javascript, bagaimanapun, anda kadang-kadang perlu melakukan sedikit pengoptimalan sendiri jika anda ingin memerah beberapa prestasi tambahan. Nasib baik, kedua-dua bahasa mempunyai pernyataan suis c-gaya.

Andy King menulis tentang versi yang sedikit diubah dari algoritma penukar gelung ini yang mengalirkan pernyataan suis dan memecahkan Peranti Duff biasa ke dalam dua gelung yang berasingan, satu untuk bakinya dan satu untuk pembukaan. Dalam Javascript, ia melakukan gelung tambahan yang mudah dalam hanya satu pertiga daripada masa biasa untuk gelung (testVal ++ adalah gelung dalaman yang biasa):

fungsi duffFasterLoop8 (lelaran) {var testVal = 0; var n = iterations% 8; jika (n> 0) {do {testVal ++; } sementara (--n); // n mestilah lebih besar dari 0 di sini} n = parseInt (lelaran / 8); lakukan {testVal ++; testVal ++; testVal ++; testVal ++; testVal ++; testVal ++; testVal ++; testVal ++; } sementara (--n); }

Ia bukan sebagai pandai sintetik seperti Peranti Duff, tetapi ia adalah cara yang baik untuk membuka giliran dalaman secara manual dan mendapatkan prestasi terbaik untuk usaha tambahan anda.

Peranti Duff Andy Optimizing JavaScript untuk Kelajuan Pelaksanaan

Kongsi

Meninggalkan Komen