খুব সুস্পষ্টভাবে সময় পাওয়ার কোনও সহজ উপায় আছে কি?
পদ্ধতি কলগুলির মধ্যে আমার কিছু বিলম্বের হিসাব করা দরকার। আরও নির্দিষ্টভাবে, আমি একটি ইউআইএসক্রোলভিউতে স্ক্রোলিংয়ের গতি গণনা করতে চাই।
খুব সুস্পষ্টভাবে সময় পাওয়ার কোনও সহজ উপায় আছে কি?
পদ্ধতি কলগুলির মধ্যে আমার কিছু বিলম্বের হিসাব করা দরকার। আরও নির্দিষ্টভাবে, আমি একটি ইউআইএসক্রোলভিউতে স্ক্রোলিংয়ের গতি গণনা করতে চাই।
উত্তর:
NSDate
এবং timeIntervalSince*
পদ্ধতিগুলি এমনটি ফিরে আসবে NSTimeInterval
যা সাব-মিলিসেকেন্ড যথার্থতার সাথে দ্বিগুণ। NSTimeInterval
সেকেন্ডে হয় তবে এটি আপনাকে আরও বেশি স্পষ্টতা দিতে ডাবলটি ব্যবহার করে।
মিলিসেকেন্ড সময় যথার্থতার গণনা করার জন্য, আপনি এটি করতে পারেন:
// Get a current time for where you want to start measuring from
NSDate *date = [NSDate date];
// do work...
// Find elapsed time and convert to milliseconds
// Use (-) modifier to conversion since receiver is earlier than now
double timePassed_ms = [date timeIntervalSinceNow] * -1000.0;
সময়কালীন ডকুমেন্টেশনআপনি এখন থেকে ।
ব্যবহার করে এই ব্যবধানটি গণনা করার জন্য আরও অনেকগুলি উপায় রয়েছে NSDate
এবং আমি NSDate শ্রেণীর রেফারেন্সেNSDate
পাওয়া ক্লাস ডকুমেন্টেশনের দিকে নজর দেওয়ার পরামর্শ দেব ।
NSDate
এবং mach_absolute_time()
প্রায় 30 মিমি স্তরে। 27 বনাম 29, 36 বনাম 39, 43 বনাম 45. NSDate
আমার জন্য ব্যবহার করা সহজ ছিল এবং ফলাফলগুলি যত্ন নেওয়ার পক্ষে যথেষ্ট ছিল।
mach_absolute_time()
সঠিক পরিমাপ পেতে ব্যবহার করা যেতে পারে।
Http://developer.apple.com/qa/qa2004/qa1398.html দেখুন
এছাড়াও উপলভ্য CACurrentMediaTime()
, যা মূলত একই জিনিস তবে সহজে ব্যবহারযোগ্য ইন্টারফেসের সাথে।
(দ্রষ্টব্য: এই উত্তরটি ২০০৯ সালে লেখা হয়েছিল ma clock_gettime()
ম্যাকোস এবং আইওএসের নতুন সংস্করণগুলিতে উপলব্ধ সহজ পোসিএক্স ইন্টারফেসের জন্য পাভেল আলেক্সিভের উত্তর দেখুন ))
CACurrentMediaTime()
, যা mach_absolute_time()
সরাসরি একটিতে রূপান্তর করে double
।
elapsedNano
প্রকারভেদ Nanoseconds
, যা একটি সরল পূর্ণসংখ্যার প্রকার নয়। এটির একটি নাম UnsignedWide
, যা দুটি 32-বিট পূর্ণসংখ্যার ক্ষেত্র সহ স্ট্রাক্ট। আপনি UnsignedWideToUInt64()
যদি পছন্দ করেন তবে কাস্টের পরিবর্তে ব্যবহার করতে পারেন ।
দয়া করে ব্যবহার করবেন না NSDate
, CFAbsoluteTimeGetCurrent
অথবা gettimeofday
অতিবাহিত সময় পরিমাপ করতে। এগুলি সমস্ত সিস্টেম ঘড়ির উপর নির্ভর করে যা বিভিন্ন সময় বিভিন্ন কারণে যেমন যে কোনও সময় পরিবর্তিত হতে পারে, যেমন নেটওয়ার্ক টাইম সিঙ্ক (এনটিপি) ক্লক আপডেট করে (প্রায়শই ড্রিফ্টের জন্য সামঞ্জস্য করার জন্য ঘটে থাকে), ডিএসটি সামঞ্জস্য, লিপ সেকেন্ড ইত্যাদি।
এর অর্থ হ'ল আপনি যদি আপনার ডাউনলোড বা আপলোডের গতি পরিমাপ করেন তবে আপনি হঠাৎ স্পাইক বা আপনার সংখ্যায় ফোঁটা পাবেন যা বাস্তবে যা ঘটেছিল তার সাথে সম্পর্কিত নয়; আপনার পারফরম্যান্স পরীক্ষার অদ্ভুত ভুল outliers হবে; এবং আপনার ম্যানুয়াল টাইমার ভুল সময়সীমা পরে ট্রিগার করবে। সময় এমনকি পিছনে যেতে পারে, এবং আপনি নেতিবাচক ডেল্টাসের সাথে শেষ করতে পারেন এবং আপনি অসীম পুনরাবৃত্তি বা ডেড কোড দিয়ে শেষ করতে পারেন (হ্যাঁ, আমি এই দুটিই করেছি)।
ব্যবহার mach_absolute_time
। কার্নেল বুট হওয়ার পরে এটি আসল সেকেন্ড পরিমাপ করে। এটি একঘেয়েভাবে বৃদ্ধি পাচ্ছে (কখনই পিছনে যাবে না), এবং তারিখ এবং সময় সেটিংস দ্বারা প্রভাবিত হয় না। যেহেতু এটি কাজ করতে ব্যথা হচ্ছে তাই এখানে একটি সাধারণ মোড়ক দেওয়া যা আপনাকে দেয় NSTimeInterval
:
// LBClock.h
@interface LBClock : NSObject
+ (instancetype)sharedClock;
// since device boot or something. Monotonically increasing, unaffected by date and time settings
- (NSTimeInterval)absoluteTime;
- (NSTimeInterval)machAbsoluteToTimeInterval:(uint64_t)machAbsolute;
@end
// LBClock.m
#include <mach/mach.h>
#include <mach/mach_time.h>
@implementation LBClock
{
mach_timebase_info_data_t _clock_timebase;
}
+ (instancetype)sharedClock
{
static LBClock *g;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
g = [LBClock new];
});
return g;
}
- (id)init
{
if(!(self = [super init]))
return nil;
mach_timebase_info(&_clock_timebase);
return self;
}
- (NSTimeInterval)machAbsoluteToTimeInterval:(uint64_t)machAbsolute
{
uint64_t nanos = (machAbsolute * _clock_timebase.numer) / _clock_timebase.denom;
return nanos/1.0e9;
}
- (NSTimeInterval)absoluteTime
{
uint64_t machtime = mach_absolute_time();
return [self machAbsoluteToTimeInterval:machtime];
}
@end
CACurrentMediaTime()
QuartzCore থেকে?
@import Darwin;
পরিবর্তে#include <mach/mach_time.h>
CFAbsoluteTimeGetCurrent()
হিসেবে পরম সময় ফেরৎ double
মান, কিন্তু আমি জানি না কি তার স্পষ্টতা - এটা হতে পারে শুধুমাত্র প্রত্যেক ডজন মিলিসেকেন্ড আপডেট, অথবা এটি, আমি জানি না যে মাইক্রোসেকেন্ড আপডেট হতে পারে।
72.89674947369
এটির অন্যান্য মানগুলি বিবেচনা করে কয়েক সেকেন্ডের মানটি বেশ অস্বাভাবিক হবে। ;)
আমি ব্যবহার করব না mach_absolute_time()
কারণ এটি টিকটিকি (সম্ভবত একটি আপটাইম) ব্যবহার করে নিখুঁত সময়ের জন্য কার্নেল এবং প্রসেসরের সংমিশ্রণটির অনুসন্ধান করে।
আমি কী ব্যবহার করব:
CFAbsoluteTimeGetCurrent();
এই ফাংশনটি iOS এবং ওএসএক্স সফ্টওয়্যার এবং হার্ডওয়্যারের মধ্যে পার্থক্যটি সংশোধন করতে অনুকূলিত।
কিছু গীকিয়ার
এর মধ্যে একটি পার্থক্যের ভাগফল mach_absolute_time()
এবং AFAbsoluteTimeGetCurrent()
সর্বদা 24000011.154871 এর কাছাকাছি
এখানে আমার অ্যাপ্লিকেশন একটি লগ আছে:
দয়া করে মনে রাখবেন যে চূড়ান্ত ফলাফলের সময়টি CFAbsoluteTimeGetCurrent()
এর মধ্যে পার্থক্য
2012-03-19 21:46:35.609 Rest Counter[3776:707] First Time: 353900795.609040
2012-03-19 21:46:36.360 Rest Counter[3776:707] Second Time: 353900796.360177
2012-03-19 21:46:36.361 Rest Counter[3776:707] Final Result Time (difference): 0.751137
2012-03-19 21:46:36.363 Rest Counter[3776:707] Mach absolute time: 18027372
2012-03-19 21:46:36.365 Rest Counter[3776:707] Mach absolute time/final time: 24000113.153295
2012-03-19 21:46:36.367 Rest Counter[3776:707] -----------------------------------------------------
2012-03-19 21:46:43.074 Rest Counter[3776:707] First Time: 353900803.074637
2012-03-19 21:46:43.170 Rest Counter[3776:707] Second Time: 353900803.170256
2012-03-19 21:46:43.172 Rest Counter[3776:707] Final Result Time (difference): 0.095619
2012-03-19 21:46:43.173 Rest Counter[3776:707] Mach absolute time: 2294833
2012-03-19 21:46:43.175 Rest Counter[3776:707] Mach absolute time/final time: 23999753.727777
2012-03-19 21:46:43.177 Rest Counter[3776:707] -----------------------------------------------------
2012-03-19 21:46:46.499 Rest Counter[3776:707] First Time: 353900806.499199
2012-03-19 21:46:55.017 Rest Counter[3776:707] Second Time: 353900815.016985
2012-03-19 21:46:55.018 Rest Counter[3776:707] Final Result Time (difference): 8.517786
2012-03-19 21:46:55.020 Rest Counter[3776:707] Mach absolute time: 204426836
2012-03-19 21:46:55.022 Rest Counter[3776:707] Mach absolute time/final time: 23999996.639500
2012-03-19 21:46:55.024 Rest Counter[3776:707] -----------------------------------------------------
mach_absolute_time()
একটি দিয়ে ব্যবহার শেষ mach_timebase_info_data
এবং তারপর কি (long double)((mach_absolute_time()*time_base.numer)/((1000*1000)*time_base.denom));
। মাচ টাইমবেস পেতে, আপনি করতে পারেন(void)mach_timebase_info(&your_timebase);
#define CTTimeStart() NSDate * __date = [NSDate date]
#define CTTimeEnd(MSG) NSLog(MSG " %g",[__date timeIntervalSinceNow]*-1)
ব্যবহার:
CTTimeStart();
...
CTTimeEnd(@"that was a long time:");
আউটপুট:
2013-08-23 15:34:39.558 App-Dev[21229:907] that was a long time: .0023
NSDate
সিস্টেম ঘড়ির উপর নির্ভর করে যা যে কোনও সময় পরিবর্তিত হতে পারে, ফলস্বরূপ ভুল বা এমনকি নেতিবাচক সময়ের ব্যবধানে পরিণত হতে পারে। mach_absolute_time
পরিবর্তে সঠিক সময় ব্যয় করতে ব্যবহার করুন ।
mach_absolute_time
ডিভাইস রিবুটগুলি দ্বারা প্রভাবিত হতে পারে। পরিবর্তে সার্ভার-সময় ব্যবহার করুন।
এছাড়াও, NSNumber
ইউনিক্সের যুগের সাথে মিলিসেকেন্ডে সূচনা হওয়া 64-বিট গণনা করার পদ্ধতি এখানে রয়েছে , যদি আপনি এটি কোরডাটাতে কীভাবে সঞ্চয় করতে চান। আমার অ্যাপ্লিকেশানের জন্য এটি আমার দরকার ছিল যা এই পদ্ধতিতে তারিখগুলি সঞ্চয় করে এমন কোনও সিস্টেমের সাথে ইন্টারঅ্যাক্ট করে।
+ (NSNumber*) longUnixEpoch {
return [NSNumber numberWithLongLong:[[NSDate date] timeIntervalSince1970] * 1000];
}
উপর ভিত্তি করে ফাংশনগুলি mach_absolute_time
সংক্ষিপ্ত পরিমাপের জন্য ভাল।
তবে দীর্ঘ পরিমাপের জন্য গুরুত্বপূর্ণ সতর্কতা হ'ল ডিভাইসটি ঘুমন্ত অবস্থায় তারা টিক দেওয়া বন্ধ করে দেয়।
বুট করার পরে সময় পেতে একটি ফাংশন রয়েছে। ঘুমানোর সময় এটি থামে না। এছাড়াও, gettimeofday
মনোটোনিক নয়, তবে আমার পরীক্ষায় আমি সর্বদা দেখতে পেয়েছি যে সিস্টেমের সময় পরিবর্তন হওয়ার সাথে সাথে বুটের সময় পরিবর্তন হয়, তাই আমার মনে হয় এটি ঠিকঠাক কাজ করা উচিত।
func timeSinceBoot() -> TimeInterval
{
var bootTime = timeval()
var currentTime = timeval()
var timeZone = timezone()
let mib = UnsafeMutablePointer<Int32>.allocate(capacity: 2)
mib[0] = CTL_KERN
mib[1] = KERN_BOOTTIME
var size = MemoryLayout.size(ofValue: bootTime)
var timeSinceBoot = 0.0
gettimeofday(¤tTime, &timeZone)
if sysctl(mib, 2, &bootTime, &size, nil, 0) != -1 && bootTime.tv_sec != 0 {
timeSinceBoot = Double(currentTime.tv_sec - bootTime.tv_sec)
timeSinceBoot += Double(currentTime.tv_usec - bootTime.tv_usec) / 1000000.0
}
return timeSinceBoot
}
এবং আইওএস 10 এবং ম্যাকোস 10.12 যেহেতু আমরা ক্লক_মোনটোনিক ব্যবহার করতে পারি:
if #available(OSX 10.12, *) {
var uptime = timespec()
if clock_gettime(CLOCK_MONOTONIC_RAW, &uptime) == 0 {
return Double(uptime.tv_sec) + Double(uptime.tv_nsec) / 1000000000.0
}
}
এটি যোগ করা:
Date.timeIntervalSinceReferenceDate
- সিস্টেম সময় পরিবর্তিত হয়, একঘেয়ে নাCFAbsoluteTimeGetCurrent()
- একঘেয়ে নয়, পিছনে যেতে পারেCACurrentMediaTime()
- ডিভাইস ঘুমন্ত অবস্থায় টিক দেওয়া বন্ধ করে দেয়timeSinceBoot()
- ঘুমায় না, তবে একঘেয়ে নাও হতে পারেCLOCK_MONOTONIC
- ঘুমায় না, একঘেয়ে, আইওএস 10 সাল থেকে সমর্থিতআমি জানি এটি একটি পুরানো তবে এমনকি আমি নিজেকে এটির সাথে আবার ঘুরে বেড়াতে দেখেছি, তাই আমি ভেবেছিলাম আমার নিজের বিকল্পটি এখানে জমা দেব।
সেরা বেট হ'ল এটিতে আমার ব্লগ পোস্টটি পরীক্ষা করা: উদ্দেশ্য-সি- জিনিসগুলির সময়: একটি স্টপওয়াচ
মূলত, আমি এমন একটি ক্লাস লিখেছিলাম যা খুব বেসিক উপায়ে দেখা বন্ধ করে দেয় না তবে এনপ্যাপসুলেটেড করা হয় যাতে আপনার কেবল নিম্নলিখিতটি করা দরকার:
[MMStopwatchARC start:@"My Timer"];
// your work here ...
[MMStopwatchARC stop:@"My Timer"];
এবং আপনি এখানে দিয়ে শেষ:
MyApp[4090:15203] -> Stopwatch: [My Timer] runtime: [0.029]
লগ ইন ...
আবার, আমার পোস্টটি আরও কিছুবার জন্য দেখুন বা এটি ডাউনলোড করুন: এমএমএসটোপওয়াচ.জিপ
NSDate
সিস্টেম ঘড়ির উপর নির্ভর করে যা যে কোনও সময় পরিবর্তিত হতে পারে, ফলস্বরূপ ভুল বা এমনকি নেতিবাচক সময়ের ব্যবধানে পরিণত হতে পারে। mach_absolute_time
পরিবর্তে সঠিক সময় ব্যয় করতে ব্যবহার করুন ।
আপনি এনএসডিট ব্যবহার করে 1 ই জানুয়ারি, 1970 থেকে মিলসেকেন্ডে বর্তমান সময় পেতে পারেন:
- (double)currentTimeInMilliseconds {
NSDate *date = [NSDate date];
return [date timeIntervalSince1970]*1000;
}
তাদের জন্য আমাদের @ জেফ থম্পসনের উত্তরের সুইফ্ট সংস্করণ প্রয়োজন:
// Get a current time for where you want to start measuring from
var date = NSDate()
// do work...
// Find elapsed time and convert to milliseconds
// Use (-) modifier to conversion since receiver is earlier than now
var timePassed_ms: Double = date.timeIntervalSinceNow * -1000.0
আমি আশা করি এটি আপনাকে সাহায্য করবে
NSDate
সিস্টেম ঘড়ির উপর নির্ভর করে যা যে কোনও সময় পরিবর্তিত হতে পারে, ফলস্বরূপ ভুল বা এমনকি নেতিবাচক সময়ের ব্যবধানে পরিণত হতে পারে। mach_absolute_time
পরিবর্তে সঠিক সময় ব্যয় করতে ব্যবহার করুন ।