সুইফটে অতিবাহিত সময় পরিমাপ করুন


132

আমরা কীভাবে সুইফটে কোনও ফাংশনটি চালানোর জন্য সময় কাটাতে পারি? আমি অতিবাহিত সময়টি এভাবে প্রদর্শন করার চেষ্টা করছি: "অতিবাহিত সময় .05 সেকেন্ড"। দেখেছি যে জাভাতে , আমরা System.nanoTime () ব্যবহার করতে পারি, এটি সম্পাদন করার জন্য সুইফটে কোনও সমতুল্য পদ্ধতি রয়েছে কি?

স্যাম্পল প্রোগ্রামটি একবার দেখুন:

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");
}

1
এটি আপনার সময়-পরিমাপের সমস্যার সাথে সম্পর্কিত নয়, তবে লুপটি এর sqrt(number)পরিবর্তে থামানো যেতে পারে numberএবং আপনি আরও কিছুটা সময় বাঁচাতে পারেন - তবে প্রাইমগুলি অনুসন্ধানের জন্য আরও অনেক ধারণা রয়েছে।
হোলএক্স

@ হোলেক্স দয়া করে ব্যবহৃত অ্যালগরিদম উপেক্ষা করুন। আমি কীভাবে আমরা অতিবাহিত সময়কে মাপতে পারি তা জানার চেষ্টা করছি?
ভাকিতা

1
আপনি NSDateঅবজেক্ট ব্যবহার করতে পারেন এবং আপনি তাদের মধ্যে পার্থক্য পরিমাপ করতে পারেন।
হোলএক্স

4
আপনি যদি এক্সকোড ব্যবহার করে থাকেন তবে আমি আপনাকে নতুন কর্মক্ষমতা পরীক্ষার বৈশিষ্ট্যটি ব্যবহার করার পরামর্শ দিচ্ছি। এটি আপনার জন্য সমস্ত ভারী উত্তোলন করে এবং এমনকি এটি একাধিকবার চালায় এবং এর মানক বিচ্যুতির সাথে আপনাকে গড় সময় দেয় ...
রোশন

1
@ ডাম্বলডেড আপনি ইউনিট পরীক্ষায় সরাসরি পুরো ব্লকের কর্মক্ষমতা পরিমাপ করতে পারবেন। উদাহরণস্বরূপ, এটি দেখুন । আপনি যদি আরও একটি রান ভাঙ্গতে চান (বলুন, লাইন কোড অনুসারে লাইন করুন), টাইম প্রোফাইলার যা পরীক্ষামূলক অংশের অংশ তা পরীক্ষা করে দেখুন । এটি অনেক বেশি শক্তিশালী এবং ব্যাপক।
রওশন

উত্তর:


228

সুইফটে প্রজেক্ট অলারের সমস্যাগুলি পরিমাপ করার জন্য আমি এখানে একটি সুইফট ফাংশন লিখেছি

সুইফট 3 হিসাবে এখন গ্র্যান্ড সেন্ট্রাল ডিসপ্যাচের একটি সংস্করণ রয়েছে যা "সুইফাইফাইড"। সুতরাং সঠিক উত্তরটি সম্ভবত ডিসপ্যাচটাইম এপিআই ব্যবহার করা ।

আমার ফাংশনটি দেখতে এমন কিছু লাগবে:

// Swift 3
func evaluateProblem(problemNumber: Int, problemBlock: () -> Int) -> Answer
{
    print("Evaluating problem \(problemNumber)")

    let start = DispatchTime.now() // <<<<<<<<<< Start time
    let myGuess = problemBlock()
    let end = DispatchTime.now()   // <<<<<<<<<<   end time

    let theAnswer = self.checkAnswer(answerNum: "\(problemNumber)", guess: myGuess)

    let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds // <<<<< Difference in nano seconds (UInt64)
    let timeInterval = Double(nanoTime) / 1_000_000_000 // Technically could overflow for long running tests

    print("Time to evaluate problem \(problemNumber): \(timeInterval) seconds")
    return theAnswer
}

পুরানো উত্তর

সুইফট 1 এবং 2 এর জন্য, আমার ফাংশনটি এনএসডিট ব্যবহার করে:

// Swift 1
func evaluateProblem(problemNumber: Int, problemBlock: () -> Int) -> Answer
{
    println("Evaluating problem \(problemNumber)")

    let start = NSDate() // <<<<<<<<<< Start time
    let myGuess = problemBlock()
    let end = NSDate()   // <<<<<<<<<<   end time

    let theAnswer = self.checkAnswer(answerNum: "\(problemNumber)", guess: myGuess)

    let timeInterval: Double = end.timeIntervalSinceDate(start) // <<<<< Difference in seconds (double)

    println("Time to evaluate problem \(problemNumber): \(timeInterval) seconds")
    return theAnswer
}

নোট করুন যে টাইমিং ফাংশনগুলির জন্য এনএসডিট ব্যবহার করা নিরুৎসাহিত করা হয়েছে: " বাহ্যিক সময়ের রেফারেন্সগুলির সাথে সুসংগত হওয়ার কারণে বা ঘড়ির সুস্পষ্ট ব্যবহারকারী পরিবর্তনের কারণে সিস্টেমের সময় হ্রাস পেতে পারে। "


এটি প্রায় +/- 2 মাইক্রোসেক পর্যন্ত ফলাফল ভাল বলে মনে হচ্ছে। তবে এটি প্ল্যাটফর্মের দ্বারা পরিবর্তিত হতে পারে।
ব্যবহারকারী 1021430

6
swift3 আমার জন্য কাজ করে না, এটি 0.0114653027 দেয় যা আমি সত্যের জন্য জানি যা সত্য নয়, তারিখের সাথে একটি ফিরে আসে 4.77720803022385 সেক্রে
ক্রিশ্টি বালু

5
দুর্ভাগ্যবশত না. আপটাইম কোনও কারণে সম্পূর্ণভাবে আউট। আমার একটি পরীক্ষা রয়েছে যা বলছে 1004959766 ন্যানোসেকেন্ড (প্রায় এক সেকেন্ড), তবে প্রায় 40 সেকেন্ডের জন্য অবশ্যই চলছিল। আমি Dateপাশাপাশি ব্যবহার করেছি , এবং যথেষ্ট নিশ্চিত যে রিপোর্টটি 41.87 সেকেন্ড। আমি জানি না কী uptimeNanosecondsকরছে তবে এটি সঠিক সময়কালে রিপোর্ট করছে না।
jowie

2
আপনার নতুন সমাধানটিকে প্রাধান্য দিয়ে বড় সম্পাদনার জন্য দুঃখিত, তবে আমি এমনকি আপনার এনএসডিট কোডটি পুরোপুরি মুছে ফেলার জন্য সুপারিশ করব: এটি এনএসডিট ব্যবহার করা সম্পূর্ণ বিশ্বাসযোগ্য নয়: এনএসডিট সিস্টেম ঘড়ির উপর ভিত্তি করে তৈরি করা হয়েছে, যে কোনও সময়ে বিভিন্ন কারণে বিভিন্ন সময়ে পরিবর্তন হতে পারে যেমন নেটওয়ার্ক টাইম সিঙ্ক হিসাবে (এনটিপি) ক্লকটি আপডেট করে (প্রায়শই ড্রিফ্টের জন্য সামঞ্জস্য করতে ঘটে), ডিএসটি সমন্বয়, লিপ সেকেন্ড এবং ঘড়ির ব্যবহারকারীর ম্যানুয়াল অ্যাডজাস্টমেন্ট। অতিরিক্ত হিসাবে, আপনি সুইফট 1: সুইফট 3 ব্যবহার করে কোনও অ্যাপ অ্যাপস্টোরে প্রকাশ করতে পারবেন না সর্বনিম্ন ন্যূনতম। সুতরাং আপনার এনএসডিট কোডটি "এটি করবেন না" বলার বাইরে রাখার কোনও অর্থ নেই।
সিউর

1
@ সিউর আপনার এনএসডিট সংস্করণ সম্পর্কে সমালোচনা বৈধ (ডিএসটি পরিবর্তনগুলি এনএসডিটকে প্রভাবিত করবে না যা সর্বদা জিএমটিতে থাকে), এবং আদেশটি উল্টাতে আপনার সম্পাদনা অবশ্যই একটি উন্নতি।
জেরেমিপ 26'19

69

এই কুশলী টাইমার উপর ভিত্তি করে ক্লাস হয় CoreFoundationগুলি CFAbsoluteTime:

import CoreFoundation

class ParkBenchTimer {

    let startTime:CFAbsoluteTime
    var endTime:CFAbsoluteTime?

    init() {
        startTime = CFAbsoluteTimeGetCurrent()
    }

    func stop() -> CFAbsoluteTime {
        endTime = CFAbsoluteTimeGetCurrent()

        return duration!
    }

    var duration:CFAbsoluteTime? {
        if let endTime = endTime {
            return endTime - startTime
        } else {
            return nil
        }
    }
}

আপনি এটি এর মতো ব্যবহার করতে পারেন:

let timer = ParkBenchTimer()

// ... a long runnig task ...

println("The task took \(timer.stop()) seconds.")

4
" এই ক্রিয়াকলাপে বারবার কল করা মনোজাতীয়ভাবে ফলাফল বাড়ানোর গ্যারান্টি দেয় না। " এর ডকুমেন্টেশন অনুসারে ।
ফ্র্যাঙ্কলিন ইউ

8
আরো কনটেক্সট: "এই ফাংশন বারবার কল monotonically বৃদ্ধি ফলাফল গ্যারান্টি নেই সিস্টেমের সময় ক্ষয়ে যায়। বাহ্যিক সময় বা তথ্যসূত্র ঘড়ি একটি সুনির্দিষ্ট ব্যবহারকারী পরিবর্তনের কারণে সাথে সিঙ্ক্রোনাইজেশান কারণে ।"
ক্লাস মায়া

বিকাশকারীকে "বাহ্যিক সময়ের রেফারেন্সগুলির সাথে সিঙ্ক্রোনাইজেশন" এবং "ঘড়ির একটি সুস্পষ্ট ব্যবহারকারী পরিবর্তন" অ্যাকাউন্টে নেওয়া উচিত। আপনি কি বোঝাতে চেয়েছিলেন যে দুটি পরিস্থিতি ঘটানো অসম্ভব?
ফ্রাঙ্কলিন ইউ

@ ফ্র্যাঙ্কলিনইয়ু না, আমি কেবল এই দুটি কারণই বলতে চাই। আপনি যদি সর্বদা মনোটোনিকভাবে বর্ধমান মান অর্জনের উপর নির্ভর করেন তবে অন্যান্য বিকল্প রয়েছে।
ক্লাস

কখনও কখনও আমি একটি স্বল্প সময়ের পরিমাপ করতে ইচ্ছুক; যদি সেই সময়ে সিঙ্ক্রোনাইজেশন ঘটে তবে আমি নেতিবাচক সময়ের সাথে শেষ করতে পারি। আসলে mach_absolute_timeযা আছে যা এই সমস্যায় ভুগছে না, তাই আমি ভাবছি যে কেন এটির ব্যাপক পরিচিতি নেই। সম্ভবত এটি সঠিকভাবে নথিভুক্ত না হওয়ার কারণে।
ফ্রাঙ্কলিন ইউ

54

ব্যবহার করুন clock, ProcessInfo.systemUptimeবা DispatchTimeসহজ শুরু সময় জন্য।


যতদূর আমি জানি, অতিবাহিত সময় পরিমাপের কমপক্ষে দশটি উপায়:

মনোটোনিক ঘড়ি ভিত্তিক:

  1. ProcessInfo.systemUptime
  2. mach_absolute_timeসঙ্গে mach_timebase_infoহিসাবে উল্লেখ এই উত্তর
  3. clock()মধ্যে POSIX মান
  4. times()মধ্যে POSIX মান । (যেহেতু আমাদের ব্যবহারকারীর সময় বনাম সিস্টেম-সময় বিবেচনা করা দরকার এবং শিশু প্রক্রিয়াগুলি এতে জড়িত রয়েছে সেহেতু খুব জটিল))
  5. DispatchTime (ম্যাক টাইম এপিআই এর চারপাশে একটি মোড়ক) যেমন জেরেমিপি দ্বারা গৃহীত উত্তরে উল্লিখিত হয়েছে।
  6. CACurrentMediaTime()

প্রাচীর ঘড়ি ভিত্তিক:

(মেট্রিকের জন্য এগুলি কখনই ব্যবহার করবেন না: নীচে দেখুন কেন)

  1. NSDate/ Dateহিসাবে অন্যদের দ্বারা উল্লিখিত।
  2. CFAbsoluteTime অন্যদের দ্বারা উল্লিখিত হিসাবে
  3. DispatchWallTime
  4. gettimeofday()মধ্যে POSIX মান

বিকল্প 1, 2 এবং 3 নীচে ব্যাখ্যা করা হয়।

বিকল্প 1: ফাউন্ডেশনে প্রক্রিয়া তথ্য এপিআই

do {
    let info = ProcessInfo.processInfo
    let begin = info.systemUptime
    // do something
    let diff = (info.systemUptime - begin)
}

যেখানে diff:NSTimeIntervalসেকেন্ড দ্বারা ব্যায়িত সময়।

বিকল্প 2: ম্যাক সি এপিআই

do {
    var info = mach_timebase_info(numer: 0, denom: 0)
    mach_timebase_info(&info)
    let begin = mach_absolute_time()
    // do something
    let diff = Double(mach_absolute_time() - begin) * Double(info.numer) / Double(info.denom)
}

যেখানে diff:Doubleন্যানো সেকেন্ড দ্বারা ব্যায়িত সময়।

বিকল্প 3: পসিক্স ক্লক এপিআই

do {
    let begin = clock()
    // do something
    let diff = Double(clock() - begin) / Double(CLOCKS_PER_SEC)
}

যেখানে diff:Doubleসেকেন্ড দ্বারা ব্যায়িত সময়।

কেন না অতিবাহিত সময়ের জন্য ওয়াল-ক্লকের সময়?

এর ডকুমেন্টেশনে CFAbsoluteTimeGetCurrent:

এই ক্রিয়াকলাপে বারবার কল করা একঘেয়েভাবে ফলস্বরূপ গ্যারান্টি দেয় না।

কারণ জাভা currentTimeMillisবনাম এরnanoTime অনুরূপ :

আপনি এটি অন্য উদ্দেশ্যে ব্যবহার করতে পারবেন না। কারণটি হ'ল কোনও কম্পিউটারের ঘড়ি নিখুঁত নয়; এটি সর্বদা বয়ে যায় এবং মাঝে মাঝে সংশোধন করা প্রয়োজন। এই সংশোধনটি হয় ম্যানুয়ালি হতে পারে, বা বেশিরভাগ মেশিনের ক্ষেত্রে, এমন একটি প্রক্রিয়া রয়েছে যা চালিত হয় এবং ক্রমাগত সিস্টেম ঘড়িতে ("প্রাচীর ঘড়ি") ছোট সংশোধন জারি করে। এগুলি প্রায়শই ঘটে থাকে। এই জাতীয় আর একটি সংশোধন ঘটে যখনই একটি লিপ সেকেন্ড হয়।

এখানে CFAbsoluteTimeস্টার্ট-আপ সময়ের পরিবর্তে প্রাচীরের ঘড়ির সময় সরবরাহ করা হয়। NSDateপ্রাচীর ঘড়ির সময় এছাড়াও।


সেরা উত্তর - তবে কী, নরক, সবচেয়ে ভাল উপায় গ্রহণ করা ?!
ফ্যাটি

1
বিকল্প 5 আমার পক্ষে সবচেয়ে উপযুক্ত। আপনি যদি মাল্টি প্ল্যাটফর্ম কোড বিবেচনা করেন তবে এটি ব্যবহার করে দেখুন। ডারউইন এবং গ্লিবসি উভয় লাইব্রেরির clock()কার্যকারিতা রয়েছে।
মিশা শ্যাভাটোশেঙ্কো

সিস্টেম ক্লক ভিত্তিক সমাধানগুলির জন্য: আমার সাথে সাফল্য ছিল ProcessInfo.processInfo.systemUptime,mach_absolute_time() , DispatchTime.now()এবং CACurrentMediaTime()। তবে এর সমাধানটি clock()সেকেন্ডে সঠিকভাবে রূপান্তর করা হয়নি। সুতরাং আমি আপনার প্রথম বাক্যটি এখানে আপডেট করার পরামর্শ দেব: " সঠিক প্রারম্ভকালীন সময়ের জন্য প্রসেসিআইএনফো.সিসটেমআপটাইম বা ডিসপ্যাচটাইম ব্যবহার করুন " "
করিউর

36

সুইফ্ট 4 সংক্ষিপ্ত উত্তর:

let startingPoint = Date()
//  ... intensive task
print("\(startingPoint.timeIntervalSinceNow * -1) seconds elapsed")

এটি আপনাকে 1.02107906341553 সেকেন্ড কেটে যাওয়ার মতো কিছু মুদ্রণ করবে ( কার্যের উপর নির্ভর করে সময় অবশ্যই পরিবর্তিত হবে, আমি এই ছেলের জন্য এই পরিমাপের দশমিক যথার্থতা স্তরটি দেখার জন্য এটি প্রদর্শন করছি)।

আশা করি এটি এখন থেকে সুইফট 4-এ কাউকে সহায়তা করবে!

হালনাগাদ

আপনি যদি কোডের কিছু অংশ পরীক্ষার জেনেরিক উপায় পেতে চান তবে আমি পরবর্তী স্নিপেটটি পরামর্শ দেব:

func measureTime(for closure: @autoclosure () -> Any) {
    let start = CFAbsoluteTimeGetCurrent()
    closure()
    let diff = CFAbsoluteTimeGetCurrent() - start
    print("Took \(diff) seconds")
}

*Usage*

measureTime(for: <insert method signature here>)

**Console log**
Took xx.xxxxx seconds

কেউ ব্যাখ্যা করতে পারেন কেন * -1?
মাকসিম নিয়াজেভ

1
@ ম্যাক্সিমকন্যিয়াজেভ এটি নেতিবাচক মান বলে, মানুষ ইতিবাচক একটি চায়!
thachnb

@ স্ট্যাচএনবি "স্টার্টিংপয়েন্ট.টাইম ইন্টেরওয়ালসিনস নও" নেতিবাচক মান উত্পন্ন করে আমার কোনও ধারণা ছিল না ...
মাকসিম নিয়াজেভ

1
@ ম্যাক্সিমকেনিয়াজেভ অ্যাপল বলেছেন যে: যদি তারিখের অবজেক্টটি বর্তমান তারিখ এবং সময়ের চেয়ে আগে হয় তবে এই সম্পত্তির মূল্য নেতিবাচক।
পিটার গুয়ান

13
let start = NSDate()

for index in 1...10000 {
    // do nothing
}

let elapsed = start.timeIntervalSinceNow

// elapsed is a negative value.

2
অ্যাবস (স্টার্ট.টাইম ইন্টারভালসিনসনইউ) // <- ধনাত্মক মান
ইওনিস্ট

আমি দেখেছি বেশ সোজা এগিয়ে সমাধান, ধন্যবাদ
মিলাদিউম

10

এই ফাংশনটি কেবল অনুলিপি করুন এবং আটকান। দ্রুতগতিতে লিখিত 5. এখানে জেরেমিপি অনুলিপি করা।

func calculateTime(block : (() -> Void)) {
        let start = DispatchTime.now()
        block()
        let end = DispatchTime.now()
        let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds
        let timeInterval = Double(nanoTime) / 1_000_000_000
        print("Time: \(timeInterval) seconds")
    }

এটি ব্যবহার করুন

calculateTime {
     exampleFunc()// function whose execution time to be calculated
}

6

আপনি timeকলগুলি পরিমাপ করার জন্য একটি ফাংশন তৈরি করতে পারেন । আমি ক্লাসের উত্তর দ্বারা অনুপ্রাণিত ।

func time <A> (f: @autoclosure () -> A) -> (result:A, duration: String) {
    let startTime = CFAbsoluteTimeGetCurrent()
    let result = f()
    let endTime = CFAbsoluteTimeGetCurrent()
    return (result, "Elapsed time is \(endTime - startTime) seconds.")
}

এই ফাংশনটি আপনাকে এটিকে এটি কল করার অনুমতি দেবে time (isPrime(7)) যা ফলাফল সহ একটি টুপল এবং অতিবাহিত সময়ের স্ট্রিং বিবরণ যুক্ত করে।

আপনি যদি কেবল অতিবাহিত সময় চান তবে আপনি এটি করতে পারেন time (isPrime(7)).duration


3
"এই ক্রিয়াকলাপে বারবার কল করা একঘেয়েভাবে ফলস্বরূপ গ্যারান্টি দেয় না।" ডকুমেন্টেশন অনুযায়ী ।
ফ্রাঙ্কলিন ইউ

3

বন্ধের সাথে সম্পাদনের সময়টি পরিমাপের জন্য সহজ সহায়ক ফাংশন।

func printExecutionTime(withTag tag: String, of closure: () -> ()) {
    let start = CACurrentMediaTime()
    closure()
    print("#\(tag) - execution took \(CACurrentMediaTime() - start) seconds")
}

ব্যবহার:

printExecutionTime(withTag: "Init") {
    // Do your work here
}

ফলাফল: #Init - execution took 1.00104497105349 seconds


2

আপনি যেমন ন্যানোসেকেন্ডগুলি পরিমাপ করতে পারেন যেমন:

let startDate: NSDate = NSDate()

// your long procedure

let endDate: NSDate = NSDate()
let dateComponents: NSDateComponents = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian).components(NSCalendarUnit.CalendarUnitNanosecond, fromDate: startDate, toDate: endDate, options: NSCalendarOptions(0))
println("runtime is nanosecs : \(dateComponents.nanosecond)")

আমি কেবল "// আপনার দীর্ঘ পদ্ধতি" তে কোনও কোড না রেখে এটিকে চালিয়েছি এবং এটি 240900993 এর ফলাফল দিয়েছে যা 0.24 সেকেন্ড।
ব্যবহারকারী 1021430

কোনও ইনস্ট্যান্ট NSCalendarকরা ব্যয়বহুল প্রক্রিয়া, তবে আপনি আপনার পদ্ধতিটি চালানো শুরু করার আগে এটি করতে পারেন , সুতরাং এটি আপনার দীর্ঘ পদ্ধতির রানটাইমটিতে যুক্ত হবে না ... মনে রাখবেন NSDateউদাহরণস্বরূপ কলিং –components(_:, fromDate:)পদ্ধতিটি কল করা এবং এখনও কলিং পদ্ধতিতে সময় লাগে তাই সম্ভবত আপনি কখনই 0.0ন্যানোসেকেন্ড পাবেন না ।
হোলএক্স

এনএসক্যালেন্ডার নির্মাণকারীর চেহারা থেকে এটি প্রদর্শিত হয় যে এটি সময়ের আগে এটি তৈরি করা সম্ভব না (স্টার্টডেট একটি প্রয়োজনীয় ইনপুট)। এটি এক ধরণের অবাক লাগে যে এটি এমন একটি হোগ বলে মনে হয়।
ব্যবহারকারী 1021430

আপনি এটি করতে পারেন (আমার আপডেট হওয়া উত্তর), কোনও অতিরিক্ত প্রক্রিয়া ছাড়াই পরিমাপ করা সময়টি 6.9আমার ডিভাইসের মাইক্রোসেকেন্ড সম্পর্কে ।
হোলএক্স

শীতল ধন্যবাদ. প্রাথমিক পদ্ধতিটি এখন জেরেমিপির উত্তরের মতো, তবে রিপোর্টিং আলাদা।
ব্যবহারকারী 1021430

2

আমি এটি ব্যবহার:

public class Stopwatch {
    public init() { }
    private var start_: NSTimeInterval = 0.0;
    private var end_: NSTimeInterval = 0.0;

    public func start() {
        start_ = NSDate().timeIntervalSince1970;
    }

    public func stop() {
        end_ = NSDate().timeIntervalSince1970;
    }

    public func durationSeconds() -> NSTimeInterval {
        return end_ - start_;
    }
}

আমি জানি না এটি আগের পোস্টের চেয়ে কম বা কম নির্ভুল কিনা। তবে সেকেন্ডে অনেকগুলি দশমিক থাকে এবং কুইকসোর্টের মতো অ্যালগরিদমে ছোট কোডের পরিবর্তনগুলি দেখে মনে হয় অদলবদল () বনাম বনাম বাস্তবায়নকারী স্ব্যাপ ইত্যাদি ব্যবহার করে code

পারফরম্যান্স পরীক্ষার সময় আপনার বিল্ড অপ্টিমাইজেশানগুলি ক্র্যাঙ্ক করা মনে রাখবেন:

সুইফ্ট সংকলক অপ্টিমাইজেশন


2

সহজ উত্তরের জন্য এখানে আমার চেষ্টা:

let startTime = Date().timeIntervalSince1970  // 1512538946.5705 seconds

// time passes (about 10 seconds)

let endTime = Date().timeIntervalSince1970    // 1512538956.57195 seconds
let elapsedTime = endTime - startTime         // 10.0014500617981 seconds

মন্তব্য

  • startTimeএবং endTimeধরনের TimeInterval, যা শুধু একটি হল typealiasজন্য Double, তাই এটি সহজ এটি একটি রূপান্তর Intবা যাই হোক না কেন। উপ-মিলিসেকেন্ড যথার্থতার সাথে সময়টি সেকেন্ডে পরিমাপ করা হয়।
  • এছাড়াও দেখুন DateInterval, যা একটি আসল শুরু এবং শেষ সময় অন্তর্ভুক্ত।
  • 1970 সাল থেকে সময় ব্যবহার করা জাভা টাইমস্ট্যাম্পগুলির মতো

সবচেয়ে সহজ উপায়, দুটি স্ট্রিং এটা চাই, দ্বিতীয় দিন elapsedTime = তারিখ () timeIntervalSince1970 -। STARTTIME
FreeGor

1

আমি চলমান এবং অন্তরালের সময় পরিমাপ করার জন্য একটি লাইটওয়েট কাঠামো তৈরি করতে ক্লাসের কাছ থেকে ধারণা ধার নিয়েছি:

কোড ব্যবহার:

var timer = RunningTimer.init()
// Code to be timed
print("Running: \(timer) ") // Gives time interval
// Second code to be timed
print("Running: \(timer) ") // Gives final time

স্টপ ফাংশনটি কল করতে হবে না, কারণ মুদ্রণ ফাংশনটি সময় কেটে যাবে। সময় নষ্ট হয়ে যাওয়ার জন্য বারবার ফোন করা যেতে পারে। কোড ব্যবহারের নির্দিষ্ট সময়ে টাইমার থামানোর জন্য timer.stop()এটি সেকেন্ডের মধ্যে সময় ফিরতেও ব্যবহৃত হতে পারে: let seconds = timer.stop() টাইমারটি বন্ধ হওয়ার পরে অন্তর টাইমারটি যাবে না, তাই print("Running: \(timer) ")কোডের কয়েকটি লাইন পরেও সঠিক সময়টি দেবে।

রানিংটাইমারের কোড নীচে দেওয়া হল। এটি সুইফট ২.১-এর জন্য পরীক্ষা করা হয়েছে:

import CoreFoundation
// Usage:    var timer = RunningTimer.init()
// Start:    timer.start() to restart the timer
// Stop:     timer.stop() returns the time and stops the timer
// Duration: timer.duration returns the time
// May also be used with print(" \(timer) ")

struct RunningTimer: CustomStringConvertible {
    var begin:CFAbsoluteTime
    var end:CFAbsoluteTime

    init() {
        begin = CFAbsoluteTimeGetCurrent()
        end = 0
    }
    mutating func start() {
        begin = CFAbsoluteTimeGetCurrent()
        end = 0
    }
    mutating func stop() -> Double {
        if (end == 0) { end = CFAbsoluteTimeGetCurrent() }
        return Double(end - begin)
    }
    var duration:CFAbsoluteTime {
        get {
            if (end == 0) { return CFAbsoluteTimeGetCurrent() - begin } 
            else { return end - begin }
        }
    }
    var description:String {
    let time = duration
    if (time > 100) {return " \(time/60) min"}
    else if (time < 1e-6) {return " \(time*1e9) ns"}
    else if (time < 1e-3) {return " \(time*1e6) µs"}
    else if (time < 1) {return " \(time*1000) ms"}
    else {return " \(time) s"}
    }
}

1

এটিকে সহজে ব্যবহারের জন্য একটি সমাপ্তি ব্লকে জড়িয়ে রাখুন।

public class func secElapsed(completion: () -> Void) {
    let startDate: NSDate = NSDate()
    completion()
    let endDate: NSDate = NSDate()
    let timeInterval: Double = endDate.timeIntervalSinceDate(startDate)
    println("seconds: \(timeInterval)")
}

0

এটি স্নিপেটটি আমি নিয়ে এসেছি এবং মনে হচ্ছে এটি আমার ম্যাকবুকে সুইফট 4 এর সাথে কাজ করবে।

অন্যান্য সিস্টেমে কখনও পরীক্ষা করা হয়নি তবে আমি ভেবেছিলাম এটি যাইহোক ভাগ করে নেওয়া ভাল।

typealias MonotonicTS = UInt64
let monotonic_now: () -> MonotonicTS = mach_absolute_time

let time_numer: UInt64
let time_denom: UInt64
do {
    var time_info = mach_timebase_info(numer: 0, denom: 0)
    mach_timebase_info(&time_info)
    time_numer = UInt64(time_info.numer)
    time_denom = UInt64(time_info.denom)
}

// returns time interval in seconds
func monotonic_diff(from: MonotonicTS, to: MonotonicTS) -> TimeInterval {
    let diff = (to - from)
    let nanos = Double(diff * time_numer / time_denom)
    return nanos / 1_000_000_000
}

func seconds_elapsed(since: MonotonicTS) -> TimeInterval {
    return monotonic_diff(from: since, to:monotonic_now())
}

এটি কীভাবে ব্যবহার করা যায় তার একটি উদাহরণ এখানে:

let t1 = monotonic_now()
// .. some code to run ..
let elapsed = seconds_elapsed(since: t1)
print("Time elapsed: \(elapsed*1000)ms")

আরও একটি উপায় এটি আরও স্পষ্টভাবে করা:

let t1 = monotonic_now()
// .. some code to run ..
let t2 = monotonic_now()
let elapsed = monotonic_diff(from: t1, to: t2)
print("Time elapsed: \(elapsed*1000)ms")

0

এভাবেই লিখেছি।

 func measure<T>(task: () -> T) -> Double {
        let startTime = CFAbsoluteTimeGetCurrent()
        task()
        let endTime = CFAbsoluteTimeGetCurrent()
        let result = endTime - startTime
        return result
    }

একটি অ্যালগরিদম পরিমাপ করতে এটি এর মতো ব্যবহার করুন

let time = measure {
    var array = [2,4,5,2,5,7,3,123,213,12]
    array.sorted()
}

print("Block is running \(time) seconds.")

সময়টি কতটা সঠিক? কারণ আমি প্রতি 0.1 সেকেন্ডে আপডেট করার আগে টাইমার ব্যবহার করেছি। আমি এই উত্তরটি এবং টাইমারের সাথে
একটিটির

0

বেসিক ফাংশন টাইমিংয়ের জন্য স্ট্যাটিক সুইফট 3 ক্লাস। এটি প্রতিটি টাইমারকে নাম ধরে রাখবে। আপনি পরিমাপ শুরু করতে চান এমন সময়ে এটিকে কল করুন:

Stopwatch.start(name: "PhotoCapture")

সময় কেটে যায় এবং সময় কেটে যায় মুদ্রণের জন্য এই কল করুন:

Stopwatch.timeElapsed(name: "PhotoCapture")

এটি আউটপুট: *** ফটো ক্যাপচারটি অতিবাহিত এমএস: 1402.415125 আপনি ন্যানোস ব্যবহার করতে চান তবে "ইউজ ন্যানোস" প্যারামিটার রয়েছে। প্রয়োজন মত পরিবর্তন করতে নির্দ্বিধায় দয়া করে।

   class Stopwatch: NSObject {

  private static var watches = [String:TimeInterval]()

  private static func intervalFromMachTime(time: TimeInterval, useNanos: Bool) -> TimeInterval {
     var info = mach_timebase_info()
     guard mach_timebase_info(&info) == KERN_SUCCESS else { return -1 }
     let currentTime = mach_absolute_time()
     let nanos = currentTime * UInt64(info.numer) / UInt64(info.denom)
     if useNanos {
        return (TimeInterval(nanos) - time)
     }
     else {
        return (TimeInterval(nanos) - time) / TimeInterval(NSEC_PER_MSEC)
     }
  }

  static func start(name: String) {
     var info = mach_timebase_info()
     guard mach_timebase_info(&info) == KERN_SUCCESS else { return }
     let currentTime = mach_absolute_time()
     let nanos = currentTime * UInt64(info.numer) / UInt64(info.denom)
     watches[name] = TimeInterval(nanos)
  }

  static func timeElapsed(name: String) {
     return timeElapsed(name: name, useNanos: false)
  }

  static func timeElapsed(name: String, useNanos: Bool) {
     if let start = watches[name] {
        let unit = useNanos ? "nanos" : "ms"
        print("*** \(name) elapsed \(unit): \(intervalFromMachTime(time: start, useNanos: useNanos))")
     }
  }

}


এর সাথে আপনার পুরো কাজ mach_timebase_infoইতিমধ্যে ভাল বাস্তবায়িত হয় আপনি করেছিল সোর্স কোড এর ProcessInfo.processInfo.systemUptime। সুতরাং সহজভাবে না watches[name] = ProcessInfo.processInfo.systemUptime। এবং * TimeInterval(NSEC_PER_MSEC)আপনি যদি ন্যানোস চান।
সিউর

0

ফ্র্যাঙ্কলিন ইউ উত্তর এবং সিউর মন্তব্যের ভিত্তিতে

বিস্তারিত

  • এক্সকোড 10.1 (10 বি 61)
  • সুইফট 4.2

সমাধান ঘ

পরিমাপ করা(_:)

সমাধান 2

import Foundation

class Measurer<T: Numeric> {

    private let startClosure: ()->(T)
    private let endClosure: (_ beginningTime: T)->(T)

    init (startClosure: @escaping ()->(T), endClosure: @escaping (_ beginningTime: T)->(T)) {
        self.startClosure = startClosure
        self.endClosure = endClosure
    }

    init (getCurrentTimeClosure: @escaping ()->(T)) {
        startClosure = getCurrentTimeClosure
        endClosure = { beginningTime in
            return getCurrentTimeClosure() - beginningTime
        }
    }

    func measure(closure: ()->()) -> T {
        let value = startClosure()
        closure()
        return endClosure(value)
    }
}

সমাধানের ব্যবহার 2

// Sample with ProcessInfo class

m = Measurer { ProcessInfo.processInfo.systemUptime }
time = m.measure {
    _ = (1...1000).map{_ in Int(arc4random()%100)}
}
print("ProcessInfo: \(time)")

// Sample with Posix clock API

m = Measurer(startClosure: {Double(clock())}) { (Double(clock()) - $0 ) / Double(CLOCKS_PER_SEC) }
time = m.measure {
    _ = (1...1000).map{_ in Int(arc4random()%100)}
}
print("POSIX: \(time)")

কেন আমাদের ভেরিয়েবল বাস্তবায়ন ব্যবহার করতে হবে তা নিশ্চিত নয়। Dateযে কোনও কিছু পরিমাপ করতে ব্যবহার করা অত্যন্ত নিরুৎসাহিত (তবে systemUptimeবা clock()ঠিক আছে)। পরীক্ষার জন্য, আমরা measure(_:)ইতিমধ্যে আছে।
সিউর

1
আরেকটি দ্রষ্টব্য: ক্লোজারটিকে makingচ্ছিক কেন করা হচ্ছে?
সিউর

@ আপনি ঠিক বলেছেন! তোমার মন্তব্যের জন্য ধন্যবাদ. আমি পরে পোস্ট আপডেট করব।
ভ্যাসিলি বোদনারুকুক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.