zoukankan      html  css  js  c++  java
  • mach_absolute_time 使用

      今天看荣哥时间常用函数封装里有个不常见的函数 ,mach_absolute_time() ,经查询后感觉是个不错的函数,网上关于这个函数搜索以后简单整理来一下。

    什么事Mach? 

    时间例程依赖于所需要测量的时间域。 某些情况下使用诸如clock() 或 getrusage()函数来做简单的数学运算就足够了。如果时间例程将用于实际开发框架之外,可移植性就很重要来。

     mach_absolute_time  是一个CPU/总线依赖函数,返回一个基于系统启动后的时钟"嘀嗒"数。在macOS上可以确保它的行为,并且,它包含系统时钟所包含的所有时间区域。其可获取纳秒级的精度。

    使用mac_absolute_time时需要考虑两个因素:

    1.如何获取当前的Mach绝对时间。

    2.如何将其转换为有意义的数字。

    * 获取mach_absolute_time非常简单

    #include <stdint.h>
    
    uint64_t start = mach_absolute_time();//是纳秒
    uint64_t stop = mach_absolute_time();

    这样我们就可以得到两个值,即可获得两个时间的时间差。

    * 讲mach_absolute_time时间差转换为秒数,这稍微复杂点了,因为我们需要获得mach_absolute_time所基于的系统时间基准。

    #include <stdint.h>
    #include <mach/mach_time.h>
    
    double subtractTimes(uint64_t endTime,uint64_t startTime)
    {
      uint64_t difference = endTime - startTime;
      static double conversion = 0.0;
      if(conversion == 0.0)
      {
         mach_timebase_info_data_t info;
        kern_return_t err = mach_timebase_info(&info);
    
      //convert the timebase into seconds
      if(err ==0)
       {
          conversion = 1e-9 * (double) info.numer / (double)info.denom;  
      }        
      return conversion * (double)difference;
    }

    这里最重要的是调用mach_timebase_info. 我们传递一个结构体以返回时间基准值。最后,一旦我们获取到了系统的时间心跳,我们便能够生成一个转换因子。通常,转换是通过分子(info.numer)除以分母(info.denom).这里乘以一个1e-9来获取秒数。最后,我们获取两个时间的差值,并乘以转换因子,便得到真实的时间差。

    网速找的一个比较好的例子:

    #import <mach/mach_time.h>
    
    double machTimeToSecs(uint64_t time)
    {
      mach_timebase_info_data_t timebase;
      mach_timebase_info(&timebase);
      return(double)time *(double)timebase.number / (double)timebase.denom / 1e9;
    }

    -(void)profileDoSometing
    {
      uint64_t begin = mach_absolute_time();
      [self dosomething];
      uint64_t end = mach_absolute_time();
      NSLog(@"Time taken to doSomething %g s",machTimeToSecs(end - begin));
    }

    -(void)dosomething
    {
      for(int i = 0;i < 10000;i++){

        NSLog(@"test");
      }
    }


      

    荣哥封装的是这样的:

    + (uint64_t)getStartTime
    {
        uint64_t nStartTick = mach_absolute_time();// 单位事纳秒
        return nStartTick;
    }
    
    + (double)getDurationSecondTime:(uint64_t)nStartTick
    {
        uint64_t nTotalTick = mach_absolute_time()-nStartTick;
        double fTotalSecond = [self machTimeToSecs: nTotalTick];
        return fTotalSecond;
    }
    
    + (double)machTimeToSecs:(uint64_t)time
    {
        mach_timebase_info_data_t timebase;
        mach_timebase_info(&timebase);
        return (double)time*(double)timebase.numer/(double)timebase.denom/1e9;//ns 转换为 s
    }

    使用时候,直接调用getStartTime开始计时,调用getDurationSecondTime获得结束时间

    网上还有一个通过该函数测某方法运行时间,以便代码优化,感觉也是不错的,记录下来以便备用。

    #import <Foundation/Foundation.h>
    #import "TimeOperations.h"
    
    #define LOOPAGE 10000000
    
    CGFloat BNRTimeBlock (void (^block)(void)) {
        mach_timebase_info_data_t info;
        if (mach_timebase_info(&info) != KERN_SUCCESS) return -1.0;
        
        uint64_t start = mach_absolute_time ();
        block ();
        uint64_t end = mach_absolute_time ();
        uint64_t elapsed = end - start;
        
        uint64_t nanos = elapsed * info.numer / info.denom;
        return (CGFloat)nanos / NSEC_PER_SEC;
        
    } // BNRTimeBlock
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            
            CGFloat time;
            
            NSString *thing1 = @"hi";
            NSString *thing2 = @"hello there";
            
            time = BNRTimeBlock(^{
                for (int i = 0; i < LOOPAGE; i++) {
                    [thing1 isEqual: thing2];
                }
            });
            printf ("isEqual: time: %f
    ", time);
            
            time = BNRTimeBlock(^{
                for (int i = 0; i < LOOPAGE; i++) {
                    [thing1 isEqualToString: thing2];
                }
            });
            printf ("isEqualToString: time: %f
    ", time);
    
            
        }
        return 0;
    }
    CGFloat ComputeTimeBlock (void (^block)(void)) {
        mach_timebase_info_data_t info;
        if (mach_timebase_info(&info) != KERN_SUCCESS) return -1.0;
        
        uint64_t start = mach_absolute_time ();
        block ();
        uint64_t end = mach_absolute_time (); // 此时是纳秒
        uint64_t elapsed = end - start;
        
        uint64_t nanos = elapsed * info.numer / info.denom;
        CGFloat test =  (CGFloat)nanos / NSEC_PER_SEC;
        return test;
    }
    
    CGFloat ComputeTimeBlock2 (void (^block)(void)) {
        mach_timebase_info_data_t info;
        if (mach_timebase_info(&info) != KERN_SUCCESS) return -1.0;
        
        uint64_t start = CACurrentMediaTime(); // 此时是秒
        block ();
        uint64_t end = CACurrentMediaTime();
        uint64_t elapsed = end - start;
        
        return elapsed;
    }
    从〇开始,回到〇
  • 相关阅读:
    数据结构:图(Graph)
    数据结构:图(Graph)
    sql中的左右关联、全关联、自关联
    sql中的左右关联、全关联、自关联
    Mathematical Functions (TransactSQL)
    Mathematical Functions (TransactSQL)
    数据库中SQL实现某列的乘积(SqlSERVER)
    数据库中SQL实现某列的乘积(SqlSERVER)
    devexpress表格控件gridcontrol设置隔行变色、焦点行颜色、设置(改变)显示值、固定列不移动(附源码)
    devexpress表格控件gridcontrol设置隔行变色、焦点行颜色、设置(改变)显示值、固定列不移动(附源码)
  • 原文地址:https://www.cnblogs.com/zpsoe/p/6994811.html
Copyright © 2011-2022 走看看