Saya mencoba menggunakan waktu () untuk mengukur berbagai titik program saya.
Yang tidak saya mengerti adalah mengapa nilai-nilai di sebelum dan sesudahnya sama? Saya mengerti ini bukan cara terbaik untuk profil program saya, saya hanya ingin melihat berapa lama waktu yang dibutuhkan.
printf("**MyProgram::before time= %ld\n", time(NULL));
doSomthing();
doSomthingLong();
printf("**MyProgram::after time= %ld\n", time(NULL));
Saya telah mencoba:
struct timeval diff, startTV, endTV;
gettimeofday(&startTV, NULL);
doSomething();
doSomethingLong();
gettimeofday(&endTV, NULL);
timersub(&endTV, &startTV, &diff);
printf("**time taken = %ld %ld\n", diff.tv_sec, diff.tv_usec);
Bagaimana cara saya membaca hasil **time taken = 0 26339
? Apakah itu berarti 26.339 nanodetik = 26,3 msec?
Bagaimana **time taken = 4 45025
, apakah itu berarti 4 detik dan 25 msec?
time()
mengembalikan nilai yang berbeda.time(NULL)
... kedua kalinya Anda memanggilnya akan menjadi N detik setelah yang pertama dan dengan demikian ... berbeda (kecuali apa pun yang Anda lakukan tidak t mengambil kedua untuk menyelesaikan ... dalam hal ini, akan sama dengan yang pertama).Jawaban:
sumber
#include <chrono>
direktif dan saya akan mengubah waktu pelaporan sebagai:std::cout << "Time difference (sec) = " << (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) /1000000.0 <<std::endl;
(dan jangan lupa C ++ 11 bendera ketika kompilasi:-std=c++11
)The
time()
Fungsi ini hanya akurat ke dalam kedua, tetapi adaCLOCKS_PER_SEC
"jam" dalam satu detik. Ini adalah pengukuran yang mudah dan portabel, meskipun terlalu disederhanakan.sumber
clock()
mengukur waktu CPU, bukan waktu aktual yang berlalu (yang mungkin jauh lebih besar).Anda dapat mengabstraksi mekanisme pengukuran waktu dan menjalankan setiap waktu yang dapat dipanggil dengan kode tambahan minimal , hanya dengan dipanggil melalui struktur pengatur waktu. Plus, pada waktu kompilasi Anda dapat menentukan jenis waktu (milidetik, nanodetik dll).
Terima kasih untuk ulasan oleh Loki Astari dan saran untuk menggunakan templat variadic. Inilah sebabnya mengapa panggilan fungsi diteruskan.
Demo
Menurut komentar Howard Hinnant , yang terbaik adalah tidak melarikan diri dari sistem chrono sampai kita harus melakukannya. Jadi kelas di atas bisa memberi pengguna pilihan untuk menelepon
count
secara manual dengan memberikan metode statis tambahan (ditunjukkan dalam C ++ 14)dan paling bermanfaat bagi klien itu
Kode lengkap dapat ditemukan di sini . Upaya saya untuk membangun alat pembandingan berdasarkan chrono dicatat di sini .
Jika C ++ 17's
std::invoke
tersedia, pemanggilan callable inexecution
dapat dilakukan seperti ini:untuk menyediakan callable yang pointer ke fungsi anggota.
sumber
code_timer
) yang memerlukan waktu mulai (std::chrono::system_clock::now();
) dalam konstruktor, metodecode_timer::ellapsed
yang mengukur perbedaan antaranow()
panggilan baru dan yang ada di konstruktor , dancode_timer::reset
metode yang mengatur ulang waktu mulai kenow()
hasil baru . Untuk mengukur pelaksanaan functor dalam kode saya, saya menggunakan fungsi bebas, di luar kelas. Hal ini memungkinkan untuk mengukur waktu dari pembangunan suatu objek, hingga penyelesaian panggilan asynch.chrono
sistem sampai Anda harus (hindari penggunaan.count()
). Biarkan klien menelepon.count()
saat dipaksa (katakan untuk I / O, yang memang disayangkan). Klien mungkin ingin pasca-proses banyak durasi sebelum I / O (misalnya rata-rata) dan yang terbaik dilakukan dalamchrono
sistem.std::forward<F>(func)
?std::forward<decltype(func)>(func)
karena itu dapat berlaku untuk argumen lambdas generik (auto&& func
) di manaF
tidak ada secara sintaksis dan mudah untuk abstrak dalam makro utilitas#define fw(arg) std::forward<decltype(arg)>(arg)
yang saya lakukan di perpustakaan benchmark saya (jadi itu adalah sintaksis yang tersisa di mana saya tidak menjelaskan banyak dalam jawabannya)Seperti yang saya lihat dari pertanyaan Anda, sepertinya Anda ingin mengetahui waktu yang telah berlalu setelah eksekusi beberapa kode. Saya kira Anda akan merasa nyaman untuk melihat hasilnya dalam hitungan detik. Jika demikian, coba gunakan
difftime()
fungsi seperti yang ditunjukkan di bawah ini. Semoga ini bisa menyelesaikan masalah Anda.sumber
Hanya Windows: (Tag Linux ditambahkan setelah saya memposting jawaban ini)
Anda dapat menggunakan GetTickCount () untuk mendapatkan jumlah milidetik yang berlalu sejak sistem dimulai.
sumber
SleepEx(5000,0)
// melakukan operasi yang memakan waktu dan perbedaanafter
danbefore
hampir 5 detik.time(NULL)
mengembalikan jumlah detik yang berlalu sejak 01/01/1970 pada pukul 00:00 ( Zaman ). Jadi perbedaan antara kedua nilai tersebut adalah jumlah detik yang Anda proses.Anda bisa mendapatkan hasil yang lebih baik
getttimeofday()
, yang mengembalikan waktu saat ini dalam detik, sepertitime()
halnya juga dalam mikrodetik.sumber
fungsi waktu (NULL) akan mengembalikan jumlah detik yang berlalu sejak 01/01/1970 pada 00:00. Dan karena, fungsi itu dipanggil pada waktu yang berbeda di program Anda, itu akan selalu berbeda di C ++
sumber
Penggunaan di bawah ::
Ini mirip dengan ruang lingkup RAII
CATATAN ini bukan milik saya, tetapi saya pikir itu relevan di sini
sumber
sumber
Nilai yang dicetak oleh program kedua Anda adalah detik, dan mikrodetik.
sumber
sumber
C ++ std :: chrono memiliki keuntungan yang jelas sebagai cross-platform. Namun, itu juga memperkenalkan overhead yang signifikan dibandingkan dengan POSIX clock_gettime (). Di kotak Linux saya semua
std::chrono::xxx_clock::now()
rasa berkinerja sama:Padahal POSIX
clock_gettime(CLOCK_MONOTONIC, &time)
harus sama dengansteady_clock::now()
tetapi lebih dari x3 kali lebih cepat!Inilah tes saya, untuk kelengkapan.
Dan ini adalah output yang saya dapatkan ketika dikompilasi dengan gcc7.2 -O3:
sumber
The
time(NULL)
fungsi panggilan akan mengembalikan jumlah detik berlalu sejak EPOC: 1 Januari 1970. Mungkin apa yang Anda maksud lakukan adalah mengambil perbedaan antara dua cap waktu:sumber
Seperti yang telah dicatat orang lain, fungsi time () di pustaka standar C tidak memiliki resolusi yang lebih baik dari satu detik. Satu-satunya fungsi C yang sepenuhnya portabel yang dapat memberikan resolusi yang lebih baik tampaknya adalah clock (), tetapi yang mengukur waktu prosesor daripada waktu jam dinding. Jika seseorang konten untuk membatasi diri pada platform POSIX (misalnya Linux), maka fungsi clock_gettime () adalah pilihan yang baik.
Sejak C ++ 11, ada banyak fasilitas pengaturan waktu yang lebih baik yang menawarkan resolusi yang lebih baik dalam bentuk yang harus sangat portabel di berbagai kompiler dan sistem operasi. Demikian pula, pustaka boost :: datetime menyediakan kelas timing resolusi tinggi yang bagus yang sangat portabel.
Salah satu tantangan dalam menggunakan salah satu dari fasilitas ini adalah penundaan waktu yang diperkenalkan dengan menanyakan jam sistem. Dari bereksperimen dengan clock_gettime (), boost :: datetime dan std :: chrono, keterlambatan ini dapat dengan mudah menjadi masalah mikrodetik. Jadi, ketika mengukur durasi bagian mana pun dari kode Anda, Anda harus mengizinkan ada kesalahan pengukuran sekitar ukuran ini, atau mencoba untuk memperbaiki kesalahan nol dalam beberapa cara. Idealnya, Anda mungkin ingin mengumpulkan beberapa pengukuran waktu yang diambil oleh fungsi Anda, dan menghitung rata-rata, atau waktu maksimum / minimum yang diambil di banyak berjalan.
Untuk membantu semua masalah portabilitas dan pengumpulan statistik ini, saya telah mengembangkan pustaka cxx-rtimers yang tersedia di Github yang mencoba menyediakan API sederhana untuk blok waktu kode C ++, menghitung nol kesalahan, dan melaporkan statistik dari banyak timer yang disematkan dalam kode Anda. Jika Anda memiliki kompiler C ++ 11, Anda cukup
#include <rtimers/cxx11.hpp>
, dan menggunakan sesuatu seperti:Saat keluar dari program, Anda akan mendapatkan ringkasan statistik waktu yang ditulis ke std :: cerr seperti:
yang menunjukkan waktu rata-rata, standar-deviasinya, batas atas dan bawah, dan berapa kali fungsi ini dipanggil.
Jika Anda ingin menggunakan fungsi waktu khusus Linux, Anda bisa
#include <rtimers/posix.hpp>
, atau jika Anda memiliki perpustakaan Boost tapi kompiler C ++ yang lebih tua, Anda bisa#include <rtimers/boost.hpp>
. Ada juga versi kelas pengatur waktu ini yang dapat mengumpulkan informasi waktu statistik dari berbagai utas. Ada juga metode yang memungkinkan Anda untuk memperkirakan kesalahan nol yang terkait dengan dua kueri langsung berturut-turut dari jam sistem.sumber
Secara internal fungsi akan mengakses jam sistem, itulah sebabnya ia mengembalikan nilai yang berbeda setiap kali Anda menyebutnya. Secara umum dengan bahasa non-fungsional, ada banyak efek samping dan status tersembunyi dalam fungsi yang tidak dapat Anda lihat hanya dengan melihat nama fungsi dan argumen.
sumber
Dari apa yang dilihat, tv_sec menyimpan detik berlalu sementara tv_usec menyimpan mikrodetik berlalu secara terpisah. Dan mereka bukan konversi satu sama lain. Oleh karena itu, mereka harus diubah ke unit yang tepat dan ditambahkan untuk mendapatkan total waktu yang telah berlalu.
sumber
Di linux, clock_gettime () adalah salah satu pilihan yang baik. Anda harus menautkan perpustakaan waktu nyata (-lrt).
sumber
Saya perlu mengukur waktu eksekusi fungsi individu dalam perpustakaan. Saya tidak ingin harus membungkus setiap panggilan dari setiap fungsi dengan fungsi pengukuran waktu karena itu jelek dan memperdalam tumpukan panggilan. Saya juga tidak ingin meletakkan kode penghitung waktu di bagian atas dan bawah dari setiap fungsi karena membuat berantakan ketika fungsi tersebut dapat keluar lebih awal atau melempar pengecualian misalnya. Jadi apa yang akhirnya saya lakukan adalah membuat pengatur waktu yang menggunakan masa hidupnya sendiri untuk mengukur waktu.
Dengan cara ini saya dapat mengukur waktu dinding blok kode yang diambil dengan hanya instantiate salah satu objek ini di awal blok kode yang bersangkutan (fungsi atau ruang lingkup benar-benar) dan kemudian memungkinkan instance destructor untuk mengukur waktu yang berlalu sejak konstruksi ketika instance keluar dari ruang lingkup. Anda dapat menemukan contoh lengkapnya di sini tetapi structnya sangat sederhana:
Struct akan memanggil Anda kembali pada functor yang disediakan ketika keluar dari ruang lingkup sehingga Anda dapat melakukan sesuatu dengan informasi waktu (cetak atau simpan atau apa pun). Jika Anda perlu melakukan sesuatu yang lebih kompleks Anda bahkan bisa menggunakan
std::bind
denganstd::placeholders
untuk callback fungsi dengan argumen yang lebih.Berikut adalah contoh cepat menggunakannya:
Jika Anda ingin lebih disengaja, Anda juga dapat menggunakan
new
dandelete
untuk secara eksplisit memulai dan menghentikan timer tanpa bergantung pada pelingkupan untuk melakukannya untuk Anda.sumber
Mereka sama karena fungsi doSomething Anda terjadi lebih cepat daripada rincian waktu. Mencoba:
sumber
Alasan kedua nilai itu sama adalah karena prosedur panjang Anda Anda tidak membutuhkan waktu lama - kurang dari satu detik. Anda dapat mencoba menambahkan loop panjang (untuk (int i = 0; i <100000000; i ++);) di akhir fungsi untuk memastikan ini masalahnya, maka kita dapat pergi dari sana ...
Jika hal di atas ternyata benar, Anda akan perlu menemukan fungsi sistem yang berbeda (saya mengerti Anda bekerja di linux, jadi saya tidak dapat membantu Anda dengan nama fungsi) untuk mengukur waktu lebih akurat. Saya yakin ada fungsi simular untuk GetTickCount () di linux, Anda hanya perlu menemukannya.
sumber
Saya biasanya menggunakan yang berikut ini:
Itu sama dengan @ nikos-athanasiou yang diusulkan kecuali bahwa saya menghindari penggunaan jam yang tidak stabil dan menggunakan jumlah detik mengambang sebagai durasi.
sumber
high_resolution_clock
adalah typedef untuk salah satusystem_clock
atausteady_clock
. Jadi untuk melacak bahwastd::conditional
jikais_steady
bagian itu benar, maka Anda memilih yanghigh_resolution_clock
mana (a typedef to) thesteady_clock
. Jika itu salah maka Anda pilihsteady_clock
lagi. Cukup gunakansteady_clock
dari awal ...high_resolution_clock may be a synonym for system_clock or steady_clock
. Alasannya adalah ini:high_resolution_clock
mewakili jam dengan periode kutu terpendek, jadi apa pun implementasinya, ia memiliki dua pilihan, stabil atau tidak. Apa pun pilihan yang kita buat, mengatakan bahwa implementasi akan berbeda dari dua jam lainnya adalah seperti mengatakan kita memiliki implementasi yang lebih baik untuk jam yang stabil (atau tidak) yang kita pilih untuk tidak menggunakan (untuk jam yang stabil atau tidak). Mengetahui bagaimana itu baik, mengetahui mengapa lebih baikSebagai jawaban atas tiga pertanyaan spesifik OP .
"Yang tidak saya mengerti adalah mengapa nilai-nilai di sebelum dan sesudahnya sama? "
Pertanyaan pertama dan kode sampel menunjukkan bahwa
time()
memiliki resolusi 1 detik, jadi jawabannya adalah bahwa kedua fungsi dijalankan dalam waktu kurang dari 1 detik. Tetapi kadang-kadang itu akan (tampaknya tidak masuk akal) menginformasikan 1 detik jika tanda dua timer mengangkangi batas satu detik.Contoh berikutnya menggunakan
gettimeofday()
yang mengisi struct inidan pertanyaan kedua bertanya: "Bagaimana saya membaca hasil
**time taken = 0 26339
? Apakah itu berarti 26.339 nanodetik = 26,3 msec?"Jawaban kedua saya adalah waktu yang diperlukan adalah 0 detik dan 26339 mikrodetik, yaitu 0,026339 detik, yang menghasilkan contoh pertama yang dijalankan dalam waktu kurang dari 1 detik.
Pertanyaan ketiga bertanya: "Bagaimana
**time taken = 4 45025
, apakah itu berarti 4 detik dan 25 msec?"Jawaban ketiga saya adalah waktu yang diambil adalah 4 detik dan 45025 mikrodetik, yaitu 4,045025 detik, yang menunjukkan bahwa OP telah mengubah tugas yang dilakukan oleh dua fungsi yang sebelumnya diatur waktunya.
sumber
Contoh serupa dengan yang tersedia di sini, hanya dengan fungsi konversi tambahan + cetak.
sumber
Saya telah membuat kelas untuk secara otomatis mengukur waktu yang telah berlalu, Silakan periksa kode (c ++ 11) di tautan ini: https://github.com/sonnt174/Common/blob/master/time_measure.h
Contoh cara menggunakan TimeMeasure kelas:
sumber
Matlab
rasa!tic
memulai penghitung waktu stopwatch untuk mengukur kinerja. Fungsi ini mencatat waktu internal pada pelaksanaan perintah tic. Menampilkan waktu yang berlalu dengantoc
fungsi.sumber
Anda dapat menggunakan pustaka SFML , yang merupakan Pustaka Multimedia Sederhana dan Cepat. Ini mencakup banyak kelas yang berguna dan didefinisikan dengan baik seperti Jam, Soket, Suara, Grafik, dll. Ini sangat mudah digunakan dan sangat dianjurkan.
Ini adalah contoh untuk pertanyaan ini.
sumber