Katakanlah saya mengimplementasikan sesuatu yang sederhana seperti mencari daftar / array yang diurutkan. Fungsi (dalam c #) akan terlihat mirip dengan:
static int FindIndex(int[] sortedList, int i);
Saya bisa menerapkan dan menguji ini dalam hal fungsionalitas, tetapi untuk alasan yang jelas saya biasanya lebih suka pencarian biner daripada pencarian linear atau sesuatu yang sengaja bodoh.
Jadi pertanyaan saya adalah: Haruskah kita berusaha menulis tes yang menjamin kinerja dalam hal kompleksitas algoritmik dan jika demikian, bagaimana?
Saya sudah mulai membuat argumen di kedua sisi bagian "haruskah Anda" dari pertanyaan ini, tetapi saya ingin melihat apa yang dikatakan orang tanpa argumen saya untuk mendorong mereka.
Dalam hal "bagaimana", itu menjadi sangat menarik :) Anda bisa melihat parameterisasi operator perbandingan dan melakukan tes yang operator perbandingannya menghitung perbandingan atau sesuatu seperti itu. Tetapi hanya karena Anda tidak dapat berarti Anda harus ...
Adakah orang lain yang mempertimbangkan hal ini (mungkin)? Terima kasih.
sumber
Jawaban:
Kompleksitas algoritma adalah konstruksi teoretis dan oleh karena itu yang terbaik "diuji" dengan pensil dan kertas. Itu tidak dapat diuji secara mekanis.
Kinerja absolut dapat diuji secara mekanis dan dapat membuat unit test yang berguna. Jika kinerja penting, maka Anda dapat menentukan ambang: "kueri ini seharusnya tidak lebih dari 50 ms untuk dijalankan pada 10 6 angka, dan tidak lebih dari 60 ms pada 10 7 angka." Anda bisa membuat unit test.
Pengguna akhir tidak peduli apakah algoritme Anda linear atau logaritmik; mereka peduli apakah UI mereka masih merespons secara instan bahkan ketika mereka memiliki data setahun dalam aplikasi.
sumber
Walaupun saya tidak yakin apakah alat ini akan sangat berguna untuk pengujian unit, makalah "Kompleksitas Komputasi Empiris" oleh Goldsmith, Aiken, dan Wilkerson menjelaskan metode untuk menginstruksikan kode dan mengamati perilaku dinamisnya pada serangkaian input berbeda untuk secara empiris menurunkan kompleksitas asimptotiknya. Program yang dijelaskan dalam makalah ini bersifat open-source dan tersedia di sini .
Semoga ini membantu!
sumber
Yang utama adalah coba dengan data besar dan lihat apakah terlalu lama.
Dalam pengalaman penyesuaian kinerja saya, seperti dalam contoh ini , apa yang terjadi adalah jika beberapa algoritma (misalnya) O (n ^ 2) mungkin baik-baik saja selama persentase waktu yang dibutuhkan tidak pernah sampai ke radar.
Namun, ketika diberikan dataset dengan ukuran yang mungkin tidak terlihat tetapi setahun sekali, sebagian kecil dari total waktu yang dihisap oleh algoritma tersebut dapat menjadi dominan secara dahsyat.
Jika Anda dapat mewujudkannya dalam pengujian, itu adalah hal yang sangat baik, karena sangat mudah untuk menemukan masalahnya, sama seperti jika itu adalah loop tak terbatas yang sebenarnya.
sumber
Saya tidak berpikir apa yang ingin Anda lakukan adalah Pengujian Unit.
AFAIK, pengujian unit hanya untuk memastikan kode melakukan apa yang seharusnya dilakukan dan tidak fokus pada kinerja.
Ada jenis alat dan pola lain untuk mengukur kinerja. Salah satu yang bisa saya ingat sekarang adalah pengujian Penerimaan berfokus pada persyaratan non fungsional.
Ada beberapa yang lain seperti pengujian kinerja (yang menggunakan pengujian stres, pengujian beban, dll).
Anda juga dapat menggunakan beberapa alat stres bersama-sama dengan alat build (semut, studio build otomatis) sebagai bagian dari langkah penerapan Anda (itulah yang saya lakukan).
Jadi jawaban singkatnya adalah tidak, Anda tidak perlu khawatir tentang hal itu saat unit menguji kode.
sumber
Melewati pembanding dan memiliki yang melacak berapa kali disebut akan bekerja untuk tujuan sederhana seperti memeriksa bahwa jumlah perbandingan ketika melakukan pencarian dalam input tetap (katakanlah
new int[] { 1,2,3, ... , 1024 }
) tetap di bawah 10. Itu setidaknya akan memperjelas niat Anda tentang bagaimana algoritma seharusnya berperilaku.Saya tidak berpikir unit test adalah cara yang tepat untuk memverifikasi bahwa algoritma Anda adalah O (log n); yang akan membutuhkan banyak pembuatan data acak, beberapa penyesuaian kurva, dan mungkin statistik secara kasar untuk menentukan apakah sekelompok titik data cocok dengan runtime yang diharapkan. (Untuk algoritme ini mungkin dapat dilakukan, tetapi jika Anda mulai menyortir dll akan menjadi sulit untuk berulang kali menekan skenario terburuk).
sumber