Bagaimana kita bisa mengukur waktu yang telah berlalu untuk menjalankan fungsi di Swift? Saya mencoba untuk menampilkan waktu yang telah berlalu seperti ini: "Waktu yang berlalu adalah .05 detik". Melihat bahwa di Jawa , kita dapat menggunakan System.nanoTime (), apakah ada metode setara yang tersedia di Swift untuk mencapai ini?
Silakan lihat contoh programnya:
func isPrime(var number:Int) ->Bool {
var i = 0;
for i=2; i<number; i++ {
if(number % i == 0 && i != 0) {
return false;
}
}
return true;
}
var number = 5915587277;
if(isPrime(number)) {
println("Prime number");
} else {
println("NOT a prime number");
}
swift
time
nsdate
elapsedtime
Vaquita
sumber
sumber
sqrt(number)
bukannumber
, dan Anda dapat menyimpan waktu yang lebih sedikit - tetapi ada banyak lagi ide-ide mengoptimalkan mencari bilangan prima.NSDate
objek dan Anda dapat mengukur perbedaan di antara mereka.Jawaban:
Inilah fungsi Swift yang saya tulis untuk mengukur masalah Project Euler di Swift
Pada Swift 3, sekarang ada versi Grand Central Dispatch yang "swiftified". Jadi jawaban yang benar mungkin menggunakan API DispatchTime .
Fungsi saya akan terlihat seperti:
Jawaban lama
Untuk Swift 1 dan 2, fungsi saya menggunakan NSDate:
Perhatikan bahwa menggunakan NSdate untuk fungsi pengaturan waktu tidak disarankan: " Waktu sistem dapat menurun karena sinkronisasi dengan referensi waktu eksternal atau karena perubahan pengguna yang eksplisit dari jam. ".
sumber
Date
samping, dan tentu saja itu melaporkan 41,87 detik. Saya tidak tahu apauptimeNanoseconds
yang dilakukan, tetapi tidak melaporkan durasi yang benar.Ini adalah kelas Timer berguna berdasarkan
CoreFoundation
sCFAbsoluteTime
:Anda bisa menggunakannya seperti ini:
sumber
mach_absolute_time
yang tidak menderita dari masalah ini, jadi saya bertanya-tanya mengapa itu tidak diketahui secara luas. Mungkin hanya karena tidak terdokumentasi dengan baik.Gunakan
clock
,,ProcessInfo.systemUptime
atauDispatchTime
untuk waktu mulai yang sederhana.Sejauh yang saya tahu, setidaknya ada sepuluh cara untuk mengukur waktu yang telah berlalu:
Berbasis Jam Monoton:
ProcessInfo.systemUptime
.mach_absolute_time
denganmach_timebase_info
sebagaimana disebutkan dalam jawaban ini .clock()
dalam standar POSIX .times()
dalam standar POSIX . (Terlalu rumit karena kita perlu mempertimbangkan waktu pengguna vs waktu sistem, dan proses anak terlibat.)DispatchTime
(pembungkus sekitar API waktu Mach) sebagaimana disebutkan oleh JeremyP dalam jawaban yang diterima.CACurrentMediaTime()
.Berbasis Jam Dinding:
(jangan pernah gunakan itu untuk metrik: lihat alasannya di bawah)
NSDate
/Date
Seperti yang disebutkan oleh orang lain.CFAbsoluteTime
seperti yang disebutkan oleh orang lain.DispatchWallTime
.gettimeofday()
dalam standar POSIX .Opsi 1, 2 dan 3 diuraikan di bawah ini.
Opsi 1: API Info Proses dalam Yayasan
di mana
diff:NSTimeInterval
waktu yang berlalu oleh detik.Opsi 2: API Mach C
di mana
diff:Double
waktu yang berlalu oleh nano-detik.Opsi 3: API jam POSIX
di mana
diff:Double
waktu yang berlalu oleh detik.Mengapa Bukan Jam Dinding untuk Masa Berlalu?
Dalam dokumentasi
CFAbsoluteTimeGetCurrent
:Alasannya mirip dengan
currentTimeMillis
vsnanoTime
di Jawa :Di sini
CFAbsoluteTime
menyediakan waktu jam dinding alih-alih waktu memulai.NSDate
adalah waktu jam dinding juga.sumber
clock()
fungsi.ProcessInfo.processInfo.systemUptime
,mach_absolute_time()
,DispatchTime.now()
danCACurrentMediaTime()
. Tetapi solusi denganclock()
itu tidak mengkonversi ke detik dengan benar. Jadi saya akan menyarankan untuk memperbarui kalimat pertama Anda ke: " Gunakan ProcessInfo.systemUptime atau DispatchTime untuk waktu start-up yang akurat. "Swift 4 jawaban terpendek:
Ini akan mencetak Anda sesuatu seperti 1,02107906341553 detik berlalu (waktu tentu akan bervariasi tergantung pada tugas, saya hanya menunjukkan ini untuk kalian untuk melihat tingkat presisi desimal untuk pengukuran ini).
Semoga ini bisa membantu seseorang di Swift 4 mulai sekarang!
Memperbarui
Jika Anda ingin memiliki cara umum untuk menguji bagian-bagian kode, saya akan menyarankan potongan berikutnya:
sumber
sumber
Cukup Salin dan Tempel fungsi ini. Ditulis dengan cepat 5. Menyalin JeremyP di sini.
Gunakan seperti
sumber
Anda dapat membuat
time
fungsi untuk mengukur panggilan Anda. Saya terinspirasi oleh jawaban Klaas .Fungsi ini akan memungkinkan Anda untuk memanggilnya seperti ini
time (isPrime(7))
yang akan mengembalikan tuple yang berisi hasil dan deskripsi string dari waktu yang telah berlalu.Jika Anda hanya ingin waktu yang telah berlalu, Anda dapat melakukan ini
time (isPrime(7)).duration
sumber
Fungsi pembantu sederhana untuk mengukur waktu eksekusi dengan penutupan.
Pemakaian:
Hasil:
#Init - execution took 1.00104497105349 seconds
sumber
Anda dapat mengukur nanodetik seperti misalnya ini:
sumber
NSCalendar
prosedur yang mahal, tetapi Anda bisa melakukannya sebelum Anda mulai menjalankan prosedur Anda, jadi prosedur itu tidak akan ditambahkan ke runtime prosedur panjang Anda ... ingat memanggil pembuatan membuatNSDate
instance dan–components(_:, fromDate:)
metode panggilan masih membutuhkan waktu, jadi mungkin Anda tidak akan pernah mendapatkan0.0
nanodetik.6.9
mikrodetik pada perangkat saya.Saya menggunakan ini:
Saya tidak tahu apakah ini lebih atau kurang akurat daripada yang diposting sebelumnya. Tetapi detik memiliki banyak desimal dan tampaknya menangkap perubahan kode kecil dalam algoritma seperti QuickSort menggunakan swap () vs. menerapkan swap sendiri dll.
Ingat untuk meningkatkan optimisasi bangunan Anda saat menguji kinerja:
sumber
Inilah upaya saya untuk jawaban yang paling sederhana:
Catatan
startTime
danendTime
dari jenisnyaTimeInterval
, yang hanyatypealias
untukDouble
, jadi mudah untuk mengubahnya menjadiInt
atau apa pun. Waktu diukur dalam detik dengan presisi sub-milidetik.DateInterval
, yang mencakup waktu mulai dan berakhir yang sebenarnya.sumber
Saya telah meminjam ide dari Klaas untuk membuat struct ringan untuk mengukur berlari dan interval waktu:
Penggunaan Kode:
Fungsi berhenti tidak harus dipanggil, karena fungsi cetak akan memberikan waktu yang telah lewat. Ini dapat dipanggil berulang kali untuk mendapatkan waktu berlalu. Tetapi untuk menghentikan timer pada titik tertentu dalam penggunaan kode
timer.stop()
itu juga dapat digunakan untuk mengembalikan waktu dalam hitungan detik:let seconds = timer.stop()
Setelah timer dihentikan, timer interval tidak akan, sehinggaprint("Running: \(timer) ")
akan memberikan waktu yang benar bahkan setelah beberapa baris kode.Berikut ini adalah kode untuk RunningTimer. Ini diuji untuk Swift 2.1:
sumber
Bungkus di blok penyelesaian agar mudah digunakan.
sumber
Ini adalah cuplikan yang saya buat dan sepertinya bekerja untuk saya di Macbook saya dengan Swift 4.
Tidak pernah diuji pada sistem lain, tapi saya pikir tetap layak untuk dibagikan.
Berikut ini contoh cara menggunakannya:
Cara lain adalah melakukannya secara lebih eksplisit:
sumber
Ini adalah bagaimana saya menulisnya.
Untuk mengukur suatu algoritma, gunakan seperti itu.
sumber
Kelas Swift3 statis untuk pengaturan fungsi dasar. Ini akan melacak setiap timer dengan nama. Sebut saja seperti ini di titik yang ingin Anda ukur:
Sebut ini untuk menangkap dan mencetak waktu yang telah berlalu:
Ini adalah output: *** PhotoCapture berlalu ms: 1402.415125 Ada parameter "useNanos" jika Anda ingin menggunakan nanos. Silakan berubah sesuai kebutuhan.
}
sumber
mach_timebase_info
sudah dilaksanakan lebih baik daripada yang Anda lakukan dalam kode sumber dariProcessInfo.processInfo.systemUptime
. Jadi lakukan sajawatches[name] = ProcessInfo.processInfo.systemUptime
. Dan* TimeInterval(NSEC_PER_MSEC)
jika Anda ingin nano.Berdasarkan jawaban Franklin Yu dan komentar Cœur
Detail
Solusi 1
mengukur(_:)
Solusi 2
Penggunaan solusi 2
sumber
Date
untuk mengukur apa pun sangat tidak dianjurkan (tapisystemUptime
atauclock()
tidak apa-apa). Adapun tes, kamimeasure(_:)
sudah.