我如何分析一段代码在Objective-C / Cocoa中执行的时间长度以进行优化

时间:2022-08-05 01:06:35

Lets say I've got two interchangeable pieces of code and I want to figure out which one of them takes less processor time to execute. How would I do this?

让我说我有两个可互换的代码片段,我想弄清楚哪一个需要较少的处理器时间来执行。我该怎么办?

To get a very rough estimation I could just put NSLog() calls on either side of the code I wanted to profile, but it seems like the processor being otherwise very busy could skew the results.

为了得到一个非常粗略的估计,我可以在我想要分析的代码的任一侧放置NSLog()调用,但看起来处理器非常繁忙可能​​会使结果产生偏差。

3 个解决方案

#1


7  

Unless one of these two pieces of code is already in your app, and you've already profiled your app's overall performance to determine that the existing code is a major bottleneck, then what you're doing is called "premature optimization."

除非您的应用程序中已有这两段代码中的一条,并且您已经分析了应用程序的整体性能以确定现有代码是一个主要瓶颈,那么您所做的就是“过早优化”。

Xcode includes an excellent profiler tool called "Shark." For some versions, it's found in /Developer/Applications; for others, it's in a "Performance Tools" subdirectory.

Xcode包含一个名为“Shark”的优秀分析器工具。对于某些版本,它可以在/ Developer / Applications中找到;对于其他人来说,它位于“Performance Tools”子目录中。

Shark will tell you exactly how much time, as a percentage of overall execution time, your app is spending in each part of your code. The idea of using a tool like Shark is to follow the "80/20 rule" - your app will spend 80% of its time running 20% of its code, so for the best results you should spend 80% of your time optimizing that same 20%.

Shark将告诉您应用程序在代码的每个部分中花费的确切时间(占总执行时间的百分比)。使用像Shark这样的工具的想法是遵循“80/20规则” - 你的应用程序将花80%的时间运行20%的代码,所以为了获得最佳效果,你应该花费80%的时间来优化它同样20%。

So, to answer your question directly, assuming that you have run Shark, and you're looking to optimize the topmost bottleneck, simply replace it with your optimized code and run your app under Shark again. Then, compare the percentage of the overall time being spent in the replacement code to that of the original.

因此,要直接回答您的问题,假设您已经运行Shark,并且您希望优化最顶层的瓶颈,只需将其替换为优化的代码并再次在Shark下运行您的应用程序。然后,比较替换代码中花费的总时间与原始时间的百分比。

#2


2  

Woo shark, yay. See also Shark Remote Control. Basically, choose Sampling > Programmatic (Remote) from the menu in shark, then call chudStartRemotePerfMonitor and chudStopRemotePerfMonitor() bracketing the specific code you want to profile.

哇鲨,耶。另见鲨鱼遥控器。基本上,从shark菜单中选择Sampling> Programmatic(Remote),然后调用chudStartRemotePerfMonitor和chudStopRemotePerfMonitor()将您想要分析的特定代码包括在内。

That aside, here's a chunk of code I keep around for timing.

除此之外,这里有一大堆我需要时间安排的代码。

First the usage

首先是用法

uint64_t startTime, stopTime;
startTime = mach_absolute_time();

< work to time goes here >

stopTime = mach_absolute_time();
logMachTime_withIdentifier_(stopTime - startTime, @"10000000 class messages");

and here's the helper function, logMachTime_withIdentifier_.

这里是辅助函数logMachTime_withIdentifier_。

#import <mach/mach_time.h>
void logMachTime_withIdentifier_(uint64_t machTime, NSString *identifier) {
    static double timeScaleSeconds = 0.0;
    if (timeScaleSeconds == 0.0) {
        mach_timebase_info_data_t timebaseInfo;
        if (mach_timebase_info(&timebaseInfo) == KERN_SUCCESS) {    // returns scale factor for ns
            double timeScaleMicroSeconds = ((double) timebaseInfo.numer / (double) timebaseInfo.denom) / 1000;
            timeScaleSeconds = timeScaleMicroSeconds / 1000000;
        }
    }

    NSLog(@"%@: %g seconds", identifier, timeScaleSeconds*machTime);
}

#3


1  

Assuming you want to profile a whole app (not just a snippet of code), and that your app is written in C/C++/Objective-C (not, e.g. Ruby), and that you're using Xcode 3.0 or higher, you should also check out the Instruments application. The "Sampler" instrument will give you very similar information to Shark (though without Shark's sometimes very helpful tips on improving performance). In addition, you can track other resource utilization (GC, Core Data, network, disk I/O, etc.) that may be more important determinants of your app's performance than code efficiency (again, depending on the application). Instruments can also make use of the DTrace support in OS X 10.5 (man dtrace). You can write your own instruments using DTrace to monitory your application more specifically (e.g. calls to one or more methods).

假设您要分析整个应用程序(不只是代码片段),并且您的应用程序是用C / C ++ / Objective-C(不是,例如Ruby)编写的,并且您正在使用Xcode 3.0或更高版本,那么还应查看仪器应用程序。 “采样器”仪器将为您提供与Shark非常相似的信息(尽管没有Shark有时非常有用的提高性能的提示)。此外,您可以跟踪其他资源利用率(GC,核心数据,网络,磁盘I / O等),这些可能是应用程序性能的更重要决定因素,而不是代码效率(同样,取决于应用程序)。仪器还可以使用OS X 10.5(man dtrace)中的DTrace支持。您可以使用DTrace编写自己的乐器,以更具体地监视您的应用程序(例如,调用一个或多个方法)。

Using NSLog is a bad idea, as you suspect, because it likely makes use of the Apple System Logging system. There's a non-deterministic delay in writting a log to the asl and it showing up in the console. I'm not sure when the timestamp is set.

正如您所怀疑的,使用NSLog是个坏主意,因为它可能会使用Apple System Logging系统。将日志写入asl时会出现非确定性延迟,并且会在控制台中显示。我不确定时间戳是什么时候设置的。

#1


7  

Unless one of these two pieces of code is already in your app, and you've already profiled your app's overall performance to determine that the existing code is a major bottleneck, then what you're doing is called "premature optimization."

除非您的应用程序中已有这两段代码中的一条,并且您已经分析了应用程序的整体性能以确定现有代码是一个主要瓶颈,那么您所做的就是“过早优化”。

Xcode includes an excellent profiler tool called "Shark." For some versions, it's found in /Developer/Applications; for others, it's in a "Performance Tools" subdirectory.

Xcode包含一个名为“Shark”的优秀分析器工具。对于某些版本,它可以在/ Developer / Applications中找到;对于其他人来说,它位于“Performance Tools”子目录中。

Shark will tell you exactly how much time, as a percentage of overall execution time, your app is spending in each part of your code. The idea of using a tool like Shark is to follow the "80/20 rule" - your app will spend 80% of its time running 20% of its code, so for the best results you should spend 80% of your time optimizing that same 20%.

Shark将告诉您应用程序在代码的每个部分中花费的确切时间(占总执行时间的百分比)。使用像Shark这样的工具的想法是遵循“80/20规则” - 你的应用程序将花80%的时间运行20%的代码,所以为了获得最佳效果,你应该花费80%的时间来优化它同样20%。

So, to answer your question directly, assuming that you have run Shark, and you're looking to optimize the topmost bottleneck, simply replace it with your optimized code and run your app under Shark again. Then, compare the percentage of the overall time being spent in the replacement code to that of the original.

因此,要直接回答您的问题,假设您已经运行Shark,并且您希望优化最顶层的瓶颈,只需将其替换为优化的代码并再次在Shark下运行您的应用程序。然后,比较替换代码中花费的总时间与原始时间的百分比。

#2


2  

Woo shark, yay. See also Shark Remote Control. Basically, choose Sampling > Programmatic (Remote) from the menu in shark, then call chudStartRemotePerfMonitor and chudStopRemotePerfMonitor() bracketing the specific code you want to profile.

哇鲨,耶。另见鲨鱼遥控器。基本上,从shark菜单中选择Sampling> Programmatic(Remote),然后调用chudStartRemotePerfMonitor和chudStopRemotePerfMonitor()将您想要分析的特定代码包括在内。

That aside, here's a chunk of code I keep around for timing.

除此之外,这里有一大堆我需要时间安排的代码。

First the usage

首先是用法

uint64_t startTime, stopTime;
startTime = mach_absolute_time();

< work to time goes here >

stopTime = mach_absolute_time();
logMachTime_withIdentifier_(stopTime - startTime, @"10000000 class messages");

and here's the helper function, logMachTime_withIdentifier_.

这里是辅助函数logMachTime_withIdentifier_。

#import <mach/mach_time.h>
void logMachTime_withIdentifier_(uint64_t machTime, NSString *identifier) {
    static double timeScaleSeconds = 0.0;
    if (timeScaleSeconds == 0.0) {
        mach_timebase_info_data_t timebaseInfo;
        if (mach_timebase_info(&timebaseInfo) == KERN_SUCCESS) {    // returns scale factor for ns
            double timeScaleMicroSeconds = ((double) timebaseInfo.numer / (double) timebaseInfo.denom) / 1000;
            timeScaleSeconds = timeScaleMicroSeconds / 1000000;
        }
    }

    NSLog(@"%@: %g seconds", identifier, timeScaleSeconds*machTime);
}

#3


1  

Assuming you want to profile a whole app (not just a snippet of code), and that your app is written in C/C++/Objective-C (not, e.g. Ruby), and that you're using Xcode 3.0 or higher, you should also check out the Instruments application. The "Sampler" instrument will give you very similar information to Shark (though without Shark's sometimes very helpful tips on improving performance). In addition, you can track other resource utilization (GC, Core Data, network, disk I/O, etc.) that may be more important determinants of your app's performance than code efficiency (again, depending on the application). Instruments can also make use of the DTrace support in OS X 10.5 (man dtrace). You can write your own instruments using DTrace to monitory your application more specifically (e.g. calls to one or more methods).

假设您要分析整个应用程序(不只是代码片段),并且您的应用程序是用C / C ++ / Objective-C(不是,例如Ruby)编写的,并且您正在使用Xcode 3.0或更高版本,那么还应查看仪器应用程序。 “采样器”仪器将为您提供与Shark非常相似的信息(尽管没有Shark有时非常有用的提高性能的提示)。此外,您可以跟踪其他资源利用率(GC,核心数据,网络,磁盘I / O等),这些可能是应用程序性能的更重要决定因素,而不是代码效率(同样,取决于应用程序)。仪器还可以使用OS X 10.5(man dtrace)中的DTrace支持。您可以使用DTrace编写自己的乐器,以更具体地监视您的应用程序(例如,调用一个或多个方法)。

Using NSLog is a bad idea, as you suspect, because it likely makes use of the Apple System Logging system. There's a non-deterministic delay in writting a log to the asl and it showing up in the console. I'm not sure when the timestamp is set.

正如您所怀疑的,使用NSLog是个坏主意,因为它可能会使用Apple System Logging系统。将日志写入asl时会出现非确定性延迟,并且会在控制台中显示。我不确定时间戳是什么时候设置的。