integrasi berkesinambungan untuk perangkat lunak ilmiah


22

Saya bukan insinyur perangkat lunak. Saya seorang mahasiswa doktoral di bidang geosains.

Hampir dua tahun yang lalu saya mulai memprogram perangkat lunak ilmiah. Saya tidak pernah menggunakan integrasi berkelanjutan (CI), terutama karena pada awalnya saya tidak tahu itu ada dan saya adalah satu-satunya orang yang bekerja pada perangkat lunak ini.

Sekarang karena basis perangkat lunak berjalan, orang lain mulai tertarik padanya dan ingin berkontribusi pada perangkat lunak tersebut. Rencananya adalah orang lain di universitas lain menerapkan penambahan pada perangkat lunak inti. (Saya khawatir mereka bisa memperkenalkan bug). Selain itu, perangkat lunak menjadi sangat kompleks dan menjadi semakin sulit untuk diuji dan saya juga berencana untuk terus mengerjakannya.

Karena dua alasan ini, saya sekarang semakin berpikir untuk menggunakan CI. Karena saya tidak pernah memiliki pendidikan insinyur perangkat lunak dan tidak ada orang di sekitar saya yang pernah mendengar tentang CI (kami adalah ilmuwan, tidak ada programmer), saya merasa sulit untuk memulai proyek saya.

Saya punya beberapa pertanyaan di mana saya ingin mendapatkan saran:

Pertama-tama, penjelasan singkat tentang cara kerja perangkat lunak:

  • Perangkat lunak ini dikendalikan oleh satu file .xml yang berisi semua pengaturan yang diperlukan. Anda memulai perangkat lunak dengan hanya meneruskan jalur ke file .xml sebagai argumen input dan itu berjalan dan membuat beberapa file dengan hasilnya. Satu menjalankan tunggal dapat memakan waktu ~ 30 detik.

  • Ini adalah perangkat lunak ilmiah. Hampir semua fungsi memiliki beberapa parameter input, yang tipenya kebanyakan kelas yang cukup kompleks. Saya memiliki beberapa file .txt dengan katalog besar yang digunakan untuk membuat instance dari kelas-kelas ini.

Sekarang mari kita datang ke pertanyaan saya:

  1. tes unit, tes integrasi, tes ujung ke ujung? : Perangkat lunak saya sekarang sekitar 30.000 baris kode dengan ratusan fungsi dan ~ 80 kelas. Rasanya agak aneh bagi saya untuk mulai menulis unit test untuk ratusan fungsi yang sudah dilaksanakan. Jadi saya berpikir tentang membuat beberapa test case. Siapkan 10-20 file .xml berbeda dan biarkan perangkat lunak berjalan. Saya kira inilah yang disebut tes end-to-end? Saya sering membaca bahwa Anda seharusnya tidak melakukan ini, tetapi mungkin itu baik sebagai permulaan jika Anda sudah memiliki perangkat lunak yang berfungsi? Atau apakah itu hanya ide bodoh untuk mencoba menambahkan CI ke perangkat lunak yang sudah berfungsi.

  2. Bagaimana Anda menulis unit test jika parameter fungsi sulit dibuat? menganggap saya memiliki fungsi double fun(vector<Class_A> a, vector<Class_B>)dan biasanya, saya harus terlebih dahulu membaca beberapa file teks untuk membuat objek bertipe Class_Adan Class_B. Saya berpikir tentang membuat beberapa fungsi dummy seperti Class_A create_dummy_object()tanpa membaca di file teks. Saya juga berpikir tentang menerapkan semacam serialisasi . (Saya tidak berencana untuk menguji pembuatan objek kelas karena mereka hanya bergantung pada beberapa file teks)

  3. Bagaimana cara menulis tes jika hasilnya sangat bervariasi? Perangkat lunak saya memanfaatkan simulasi monte-carlo besar dan bekerja secara iteratif. Biasanya, Anda memiliki ~ 1000 iterasi dan di setiap iterasi, Anda membuat ~ 500-20.000 instance objek berdasarkan simulasi monte-carlo. Jika hanya satu hasil dari satu iterasi sedikit berbeda, seluruh iterasi yang akan datang benar-benar berbeda. Bagaimana Anda menghadapi situasi ini? Saya kira ini poin besar terhadap tes end-to-end, karena hasil akhirnya sangat bervariasi?

Saran lain dengan CI sangat dihargai.



1
Bagaimana Anda tahu bahwa perangkat lunak Anda berfungsi dengan benar? Bisakah Anda menemukan cara untuk mengotomatiskan pemeriksaan itu sehingga Anda dapat menjalankannya pada setiap perubahan? Itu harus menjadi langkah pertama Anda ketika memperkenalkan CI ke proyek yang ada.
Bart van Ingen Schenau

Bagaimana Anda memastikan perangkat lunak Anda menghasilkan hasil yang dapat diterima di tempat pertama? Apa yang membuat Anda yakin itu benar-benar "berhasil"? Jawaban untuk kedua pertanyaan akan memberi Anda banyak bahan untuk menguji perangkat lunak Anda sekarang dan di masa depan.
Polygnome

Jawaban:


23

Menguji perangkat lunak ilmiah sulit, baik karena masalah subjek yang kompleks dan karena proses pengembangan ilmiah yang khas (alias. Retas hingga berfungsi, yang biasanya tidak menghasilkan desain yang dapat diuji). Ini agak ironis mengingat sains harus dapat direproduksi. Perubahan apa yang dibandingkan dengan perangkat lunak "normal" bukanlah apakah tes itu berguna (ya!), Tetapi jenis tes mana yang sesuai.

Menangani keacakan: semua perangkat lunak Anda HARUS dapat direproduksi. Jika Anda menggunakan teknik Monte Carlo, Anda harus memungkinkan untuk menyediakan benih spesifik untuk generator angka acak.

  • Sangat mudah untuk melupakan ini misalnya ketika menggunakan rand()fungsi C yang tergantung pada keadaan global.
  • Idealnya, generator angka acak dilewatkan sebagai objek eksplisit melalui fungsi Anda. randomHeader perpustakaan standar C ++ 11 membuat ini jauh lebih mudah.
  • Alih-alih berbagi keadaan acak di seluruh modul perangkat lunak, saya merasa berguna untuk membuat RNG kedua yang diunggulkan oleh nomor acak dari RNG pertama. Kemudian, jika jumlah permintaan ke RNG oleh modul lain berubah, urutan yang dihasilkan oleh RNG pertama tetap sama.

Tes integrasi baik-baik saja. Mereka pandai memverifikasi bahwa berbagai bagian dari perangkat lunak Anda bermain bersama dengan benar, dan untuk menjalankan skenario konkret.

  • Sebagai tingkat kualitas minimum "itu tidak crash" sudah bisa menjadi hasil tes yang bagus.
  • Untuk hasil yang lebih kuat, Anda juga harus memeriksa hasilnya terhadap beberapa baseline. Namun, cek ini harus agak toleran, mis. Akun untuk kesalahan pembulatan. Juga dapat bermanfaat untuk membandingkan statistik ringkasan alih-alih baris data lengkap.
  • Jika memeriksa terhadap baseline akan terlalu rapuh, periksa apakah outputnya valid dan memenuhi beberapa sifat umum. Ini dapat bersifat umum ("lokasi yang dipilih harus berjarak setidaknya 2 km") atau khusus skenario, misalnya "lokasi yang dipilih harus berada dalam area ini".

Saat menjalankan tes integrasi, sebaiknya tulis pelari uji sebagai program atau skrip terpisah. Pelari uji ini melakukan pengaturan yang diperlukan, menjalankan yang dapat dieksekusi untuk diuji, memeriksa semua hasil, dan membersihkan setelahnya.

Pemeriksaan gaya uji unit bisa sangat sulit untuk dimasukkan ke dalam perangkat lunak ilmiah karena perangkat lunak belum dirancang untuk itu. Secara khusus, unit test menjadi sulit ketika sistem yang diuji memiliki banyak ketergantungan / interaksi eksternal. Jika perangkat lunak tidak murni berorientasi objek, umumnya tidak mungkin untuk mengejek / mematikan dependensi tersebut. Saya telah menemukan yang terbaik untuk sebagian besar menghindari tes unit untuk perangkat lunak tersebut, kecuali untuk fungsi matematika murni dan fungsi utilitas.

Bahkan beberapa tes lebih baik daripada tidak ada tes. Dikombinasikan dengan centang "harus dikompilasi" itu sudah merupakan awal yang baik menuju integrasi berkelanjutan. Anda selalu dapat kembali dan menambahkan lebih banyak tes nanti. Anda kemudian dapat memprioritaskan area kode yang lebih cenderung rusak, misalnya karena mereka mendapatkan lebih banyak aktivitas pengembangan. Untuk melihat bagian mana dari kode Anda yang tidak dicakup oleh tes unit, Anda dapat menggunakan alat cakupan kode.

Pengujian manual: Khusus untuk domain masalah yang kompleks, Anda tidak akan dapat menguji semuanya secara otomatis. Misal saya sedang mengerjakan masalah pencarian stokastik. Jika saya menguji bahwa perangkat lunak saya selalu menghasilkan hasil yang sama , saya tidak dapat memperbaikinya tanpa melanggar tes. Sebagai gantinya, saya membuatnya lebih mudah untuk melakukan tes manual : Saya menjalankan perangkat lunak dengan seed tetap dan mendapatkan visualisasihasil (tergantung pada preferensi Anda, R, Python / Pyplot, dan Matlab semuanya memudahkan untuk mendapatkan visualisasi set data berkualitas tinggi Anda). Saya dapat menggunakan visualisasi ini untuk memverifikasi bahwa tidak ada yang salah. Demikian pula, melacak kemajuan perangkat lunak Anda melalui keluaran log dapat menjadi teknik pengujian manual yang layak, setidaknya jika saya dapat memilih jenis peristiwa yang akan dicatat.


7

Rasanya agak aneh bagi saya untuk mulai menulis unit test untuk ratusan fungsi yang sudah diimplementasikan.

Anda akan ingin (biasanya) menulis tes saat Anda mengubah fungsi tersebut. Anda tidak perlu duduk dan menulis ratusan tes unit untuk fungsi yang ada, yang akan (sebagian besar) membuang-buang waktu. Perangkat lunak ini (mungkin) berfungsi dengan baik. Inti dari tes ini adalah untuk memastikan perubahan di masa depan tidak merusak perilaku lama. Jika Anda tidak pernah mengubah fungsi tertentu lagi, mungkin tidak ada gunanya meluangkan waktu untuk mengujinya (karena saat ini berfungsi, selalu bekerja, dan kemungkinan akan terus bekerja). Saya sarankan membaca Bekerja Efektif Dengan Kode Legacyoleh Michael Feathers di bagian depan ini. Dia punya beberapa strategi umum yang hebat untuk menguji hal-hal yang sudah ada, termasuk teknik pemecahan ketergantungan, tes karakterisasi (salin / tempel fungsi keluaran ke dalam rangkaian uji untuk memastikan Anda mempertahankan perilaku regresi), dan banyak lagi.

Bagaimana Anda menulis unit test jika parameter fungsi sulit dibuat?

Idealnya, Anda tidak melakukannya. Alih-alih, Anda membuat parameter lebih mudah dibuat (dan karenanya membuat desain Anda lebih mudah untuk diuji). Memang, perubahan desain membutuhkan waktu, dan perbaikan ini bisa sulit pada proyek-proyek warisan seperti milik Anda. TDD (Test Driven Development) dapat membantu dengan ini. Jika parameternya sangat sulit untuk dibuat, Anda akan memiliki banyak kesulitan menulis tes dengan gaya tes pertama.

Dalam jangka pendek, gunakan cemoohan, tapi hati-hati dengan cemoohan dan masalah yang menyertainya dalam jangka panjang. Namun, ketika saya tumbuh sebagai insinyur perangkat lunak, saya menyadari bahwa tiruan hampir selalu merupakan aroma mini yang mencoba menyelesaikan beberapa masalah yang lebih besar dan tidak menangani masalah inti. Saya suka menyebutnya sebagai "pembungkus kotoran", karena jika Anda meletakkan selembar kertas timah pada sedikit kotoran anjing di karpet Anda, masih bau. Yang harus Anda lakukan adalah bangun, ambil kotorannya, dan buang ke tempat sampah, lalu buang sampah. Ini jelas lebih banyak pekerjaan, dan Anda berisiko mendapatkan kotoran di tangan Anda, tetapi lebih baik untuk Anda dan kesehatan Anda dalam jangka panjang. Jika Anda terus membungkusnya, Anda tidak ingin tinggal di rumah lebih lama. Mock serupa di alam.

Misalnya, jika Anda memiliki Class_Ainstantiate yang sulit karena Anda harus membaca 700 file, maka Anda bisa mengejeknya. Hal berikutnya yang Anda tahu, mock Anda menjadi ketinggalan zaman, dan yang sebenarnya Class_A melakukan sesuatu yang sangat berbeda dari mock, dan tes Anda masih berjalan meskipun harus gagal. Solusi yang lebih baik adalah memecah Class_Amenjadi lebih mudah digunakan / menguji komponen, dan menguji komponen-komponen itu sebagai gantinya. Mungkin menulis satu tes integrasi yang benar-benar mengenai disk dan pastikan Class_Abekerja secara keseluruhan. Atau mungkin hanya memiliki konstruktor untuk Class_Aitu Anda dapat instantiate dengan string sederhana (mewakili data Anda) daripada harus membaca dari disk.

Bagaimana cara menulis tes jika hasilnya sangat bervariasi?

Beberapa tips:

1) Gunakan invers (atau lebih umum, pengujian berbasis properti). Apa manfaatnya [1,2,3,4,5]? Tidak ada ide. Apa ifft(fft([1,2,3,4,5]))? Seharusnya [1,2,3,4,5](atau dekat dengan itu, kesalahan floating point mungkin muncul).

2) Gunakan pernyataan "dikenal". Jika Anda menulis fungsi determinan, mungkin sulit untuk mengatakan apa determinan dari matriks 100x100. Tapi Anda tahu bahwa penentu matriks identitas adalah 1, bahkan jika itu 100x100. Anda juga tahu bahwa fungsi tersebut harus mengembalikan 0 pada matriks yang tidak dapat dibalik (seperti 100x100 penuh dari semua 0s).

3) Gunakan konfirmasi kasar, bukan konfirmasi yang tepat . Saya menulis beberapa kode beberapa waktu lalu yang mendaftarkan dua gambar dengan menghasilkan titik pengikat yang membuat pemetaan antara gambar dan melakukan warp di antara mereka untuk membuat mereka cocok. Itu bisa mendaftar pada tingkat sub-pixel. Bagaimana Anda bisa mengujinya? Hal-hal seperti:

EXPECT_TRUE(reg(img1, img2).size() < min(img1.size(), img2.size()))

karena Anda hanya dapat mendaftar pada bagian yang tumpang tindih, gambar yang terdaftar harus lebih kecil atau sama dengan gambar terkecil Anda), dan juga:

scale = 255
EXPECT_PIXEL_EQ_WITH_TOLERANCE(reg(img, img), img, .05*scale)

karena gambar yang terdaftar untuk dirinya sendiri harus TUTUP untuk dirinya sendiri, tetapi Anda mungkin mengalami sedikit lebih banyak dari kesalahan floating point karena algoritma yang ada, jadi cukup periksa setiap piksel dengan +/- 5% dari rentang yang valid (0-255 adalah rentang umum, skala abu-abu). Setidaknya harus memiliki ukuran yang sama. Anda bahkan dapat hanya merokok tes (mis. Panggilan itu dan pastikan itu tidak crash). Secara umum, teknik ini lebih baik untuk tes yang lebih besar di mana hasil akhirnya tidak dapat (dengan mudah) dihitung secara apriori untuk menjalankan tes.

4) Gunakan ATAU MENYIMPAN seed number acak untuk RNG Anda.

Berjalan memang harus direproduksi. Adalah salah, bagaimanapun, bahwa satu-satunya cara untuk mendapatkan proses yang dapat direproduksi adalah dengan menyediakan benih khusus untuk generator angka acak. Terkadang pengujian keacakan bernilai . Saya telah melihat bug dalam kode ilmiah yang muncul dalam kasus degenerasi yang dihasilkan secara acak . Alih-alih selalu memanggil fungsi Anda dengan seed yang sama, hasilkan seed acak , lalu gunakan seed itu, dan catat nilai seed tersebut. Dengan begitu setiap proses memiliki seed acak berbeda , tetapi jika Anda mendapatkan crash, Anda dapat menjalankan kembali hasilnya dengan menggunakan seed yang telah Anda login ke debug. Saya benar-benar menggunakan ini dalam praktek dan itu menghancurkan bug, jadi saya pikir saya akan menyebutkannya.Kelemahan: Anda harus mencatat uji coba Anda. Terbalik: Koreksi dan bug nuking.

HTH.


2
  1. Jenis tes

    • Rasanya agak aneh bagi saya untuk mulai menulis unit test untuk ratusan fungsi yang sudah dilaksanakan

      Pikirkan sebaliknya: jika sebuah patch yang menyentuh beberapa fungsi memecah salah satu tes ujung ke ujung Anda, bagaimana Anda akan mencari tahu yang mana masalahnya?

      Jauh lebih mudah untuk menulis unit test untuk fungsi individual daripada untuk keseluruhan program. Jauh lebih mudah untuk memastikan Anda memiliki cakupan yang baik dari fungsi individu. Jauh lebih mudah untuk memperbaiki fungsi ketika Anda yakin unit test akan menangkap setiap kasus sudut yang rusak.

      Tes unit penulisan untuk fungsi-fungsi yang sudah ada adalah sangat normal bagi siapa saja yang telah bekerja pada basis kode warisan. Mereka adalah cara yang baik untuk mengonfirmasi pemahaman Anda tentang fungsi di tempat pertama dan, setelah ditulis, mereka adalah cara yang baik untuk menemukan perubahan perilaku yang tidak terduga.

    • Tes end-to-end juga bermanfaat. Jika lebih mudah untuk menulis, lakukan semua itu terlebih dahulu dan tambahkan unit test ad-hoc untuk mencakup fungsi yang paling Anda khawatirkan akan dilanggar orang lain. Anda tidak harus melakukan semuanya sekaligus.

    • Ya, menambahkan CI ke perangkat lunak yang ada masuk akal, dan normal.

  2. Cara menulis unit test

    Jika benda Anda benar-benar mahal dan / atau rumit, tulis ejekan. Anda bisa menghubungkan tes menggunakan tiruan secara terpisah dari tes menggunakan benda nyata, daripada menggunakan polimorfisme.

    Anda seharusnya memiliki cara mudah untuk membuat instance - fungsi untuk membuat instance dummy adalah hal yang umum - tetapi memiliki tes untuk proses pembuatan yang sebenarnya juga masuk akal.

  3. Hasil variabel

    Anda harus memiliki beberapa invarian untuk hasilnya. Uji itu, bukan nilai numerik tunggal.

    Anda dapat memberikan generator nomor acak palsu jika kode monte carlo Anda menerimanya sebagai parameter, yang akan membuat hasil yang dapat diprediksi setidaknya untuk algoritma yang terkenal, tetapi rapuh kecuali benar-benar mengembalikan nomor yang sama setiap kali.


1
  1. Tidak pernah merupakan ide bodoh untuk menambahkan CI. Dari pengalaman saya tahu ini adalah cara untuk pergi ketika Anda memiliki proyek open source di mana orang bebas untuk berkontribusi. CI memungkinkan Anda untuk menghentikan orang-orang dari menambah atau mengubah kode jika kode tersebut merusak program Anda, sehingga hampir tak ternilai dalam memiliki basis kode yang berfungsi.

    Ketika mempertimbangkan tes, Anda tentu dapat memberikan beberapa tes end-to-end (saya pikir ini adalah subkategori tes integrasi) untuk memastikan bahwa aliran kode Anda berfungsi sebagaimana mestinya. Anda harus menyediakan setidaknya beberapa tes unit dasar untuk memastikan bahwa fungsi menghasilkan nilai yang benar, karena bagian dari tes integrasi dapat mengkompensasi kesalahan lain yang dibuat selama pengujian.

  2. Uji penciptaan objek adalah sesuatu yang cukup sulit dan memang sulit. Anda benar karena ingin membuat benda tiruan. Objek-objek ini harus memiliki beberapa nilai default, tetapi tepi kasus, yang Anda tentu tahu apa yang seharusnya menjadi output.

  3. Masalahnya dengan buku-buku tentang subjek ini adalah bahwa lanskap CI (dan bagian lain dari devops) berevolusi begitu cepat apa pun dalam sebuah buku mungkin akan ketinggalan zaman beberapa bulan kemudian. Saya tidak tahu ada buku yang bisa membantu Anda, tetapi Google harus, seperti biasa, menjadi penyelamat Anda.

  4. Anda harus menjalankan tes Anda sendiri beberapa kali dan melakukan analisis statistik. Dengan cara itu Anda bisa menerapkan beberapa kasus uji di mana Anda mengambil median / rata-rata beberapa berjalan dan membandingkannya dengan analisis Anda, untuk mengetahui nilai-nilai apa yang benar.

Beberapa tips:

  • Gunakan integrasi alat CI dalam platform GIT Anda untuk menghentikan kode yang rusak dari memasuki basis kode Anda.
  • berhenti menggabungkan kode sebelum peer-review dilakukan oleh pengembang lain. Ini membuat kesalahan lebih mudah diketahui dan sekali lagi menghentikan kode yang rusak dari memasukkan basis kode Anda.

1

Dalam balasan sebelum amon sudah disebutkan beberapa poin yang sangat penting. Izinkan saya menambahkan lagi:

1. Perbedaan antara pengembangan perangkat lunak ilmiah dan perangkat lunak komersial

Untuk perangkat lunak ilmiah, tentu saja fokusnya adalah pada masalah ilmiah. Masalahnya lebih pada penanganan latar belakang teoritis, menemukan metode numerik terbaik, dll. Perangkat lunak ini hanya satu, lebih atau kurang, bagian kecil dari pekerjaan.

Perangkat lunak ini dalam banyak kasus ditulis oleh satu atau hanya beberapa orang. Ini sering ditulis untuk proyek tertentu. Ketika proyek selesai dan semuanya diterbitkan, dalam banyak kasus, perangkat lunak tidak lagi diperlukan.

Perangkat lunak komersial biasanya dikembangkan oleh tim besar dalam periode waktu yang lebih lama. Ini membutuhkan banyak perencanaan untuk arsitektur, desain, tes unit, tes integrasi dll. Perencanaan ini membutuhkan banyak waktu dan pengalaman. Dalam lingkungan ilmiah, biasanya tidak ada waktu untuk itu.

Jika Anda ingin mengonversi proyek Anda ke perangkat lunak yang mirip dengan perangkat lunak komersial, Anda harus memeriksa yang berikut:

  • Anda punya waktu dan sumber daya?
  • Apa perspektif jangka panjang dari perangkat lunak? Apa yang akan terjadi dengan perangkat lunak ketika Anda menyelesaikan pekerjaan Anda dan meninggalkan universitas?

2. Tes ujung ke ujung

Jika perangkat lunak semakin kompleks dan beberapa orang mengerjakannya, tes harus dilakukan. Tetapi seperti yang telah disebutkan Amon , menambahkan unit test ke perangkat lunak ilmiah cukup sulit. Jadi, Anda harus menggunakan pendekatan yang berbeda.

Karena perangkat lunak Anda mendapatkan input dari file, seperti kebanyakan perangkat lunak ilmiah, itu sempurna untuk membuat beberapa sampel input dan file output. Anda harus menjalankan tes tersebut secara otomatis pada setiap rilis dan membandingkan hasilnya dengan sampel Anda. Ini bisa menjadi pengganti yang sangat baik untuk unit test. Anda mendapatkan tes integrasi dengan cara ini juga.

Tentu saja, untuk mendapatkan hasil yang dapat direproduksi, Anda harus menggunakan seed yang sama untuk generator nomor acak Anda, seperti yang sudah ditulis amon .

Contohnya harus mencakup hasil khas perangkat lunak Anda. Ini juga harus mencakup kasus tepi ruang parameter dan algoritma numerik.

Anda harus mencoba menemukan contoh yang tidak perlu terlalu banyak waktu untuk berjalan, tetapi masih mencakup kasus uji yang khas.

3. Integrasi berkelanjutan

Karena menjalankan contoh uji mungkin memerlukan waktu, saya pikir integrasi berkesinambungan tidak layak. Anda mungkin harus mendiskusikan bagian tambahan dengan kolega Anda. Misalnya, mereka harus cocok dengan metode numerik yang digunakan.

Jadi saya pikir lebih baik melakukan integrasi dengan cara yang terdefinisi dengan baik setelah membahas latar belakang teoritis dan metode numerik, pengujian hati-hati, dll.

Saya tidak berpikir bahwa itu adalah ide yang baik untuk memiliki semacam otomatisme untuk integrasi berkelanjutan.

Omong-omong, apakah Anda menggunakan sistem kontrol versi?

4. Menguji algoritma numerik Anda

Jika Anda membandingkan hasil numerik, misalnya saat memeriksa hasil tes Anda, Anda tidak harus memeriksa angka mengambang untuk kesetaraan. Mungkin selalu ada kesalahan bulat. Alih-alih, periksa apakah perbedaannya lebih rendah dari ambang tertentu.

Ini juga merupakan ide bagus untuk memeriksa algoritma Anda terhadap algoritma yang berbeda atau merumuskan masalah ilmiah dengan cara yang berbeda dan membandingkan hasilnya. Jika Anda mendapatkan hasil yang sama menggunakan dua atau lebih cara independen, ini adalah indikasi yang baik bahwa teori Anda dan implementasi Anda sudah benar.

Anda dapat melakukan tes-tes tersebut dalam kode pengujian Anda dan menggunakan algoritma tercepat untuk kode produksi Anda.


0

Saran saya adalah memilih dengan cermat bagaimana Anda mengeluarkan usaha Anda. Di bidang saya (bioinformatika), algoritma canggih berubah begitu cepat sehingga menghabiskan energi untuk membuktikan kesalahan kode Anda mungkin lebih baik dihabiskan untuk algoritma itu sendiri.

Yang mengatakan, apa yang dihargai adalah:

  • apakah ini metode terbaik saat itu, dalam hal algoritma?
  • betapa mudahnya port untuk platform komputasi yang berbeda (lingkungan HPC yang berbeda, rasa OS dll)
  • kekokohan - apakah ini berjalan pada dataset MY?

Naluri Anda untuk membuat basis kode anti peluru itu mulia, tetapi patut diingat bahwa ini bukan produk komersial. Jadikan semudah mungkin, tahan kesalahan (untuk tipe pengguna Anda), nyaman bagi orang lain untuk berkontribusi, lalu fokus pada algoritme itu sendiri

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.