Objective C的自定义性能分析器

时间:2012-03-19 10:48:55

标签: objective-c performance profiling profile

我想为Objective C创建一个简单易用且轻量级的性能配置文件框架。我的目标是测量应用程序的瓶颈。

只是提到我不是初学者而且我知道仪器/时间分析器。这不是我想要的。 Time Profiler是一个很棒的工具,但是面向开发人员。我想要一个可以从QA或预生产用户那里收集性能数据的框架,甚至可以在真实的生产环境中集成以收集真实数据。

该框架的主要部分是能够测量在Objective C消息中花费了多少时间(我将仅分析Objective C消息)。

最简单的方法是在消息开头启动计时器并在结束时停止计时器。这是最简单的方法,但它的缺点是它很繁琐且容易出错 - 如果任何消息有超过1个返回路径,那么它将需要在每次返回之前添加“stop timer”代码。

我正在考虑使用方法调配(只是要注意我知道Apple对方法调配不满意,但这些配置文件只会在内部使用 - 不会上传到App Store)。

我的想法是标记我想要分析的每条消息,并自动生成方法混合方法的代码(可能使用宏)。启动时,应用程序将使用生成的选择器调整原始选择器。生成的只会启动一个计时器,将调用原始方法,然后将停止计时器。所以一般来说,混合方法只是原始方法的包装。

上述想法的一个问题是,我想不出如何自动生成用于调配的方法的简单方法。

所以如果有人有任何想法如何自动化整个过程,我将非常感激。完美的场景就是在提到我想要分析的类和选择器的任何地方编写一行代码,其余部分自动生成。

如果您对如何衡量表现有任何其他想法(除了方法调整之外),也将非常感激。

1 个答案:

答案 0 :(得分:1)

我想出了一个对我有用的解决方案。首先只是为了澄清我无法找到一种简单(性能快速)的方法,只使用选择器名称为任意选择器(即具有任意参数和返回值)自动生成适当的混合方法。所以我不得不为每个选择器添加参数类型和返回值,而不仅仅是选择器名称。实际上,创建一个能够解析所有源文件并自动检测参数类型和我们想要分析的选择器的返回值(并准备混合方法)的小工具应该相对容易。现在我不需要这样的自动化解决方案。

所以现在我的解决方案包括上面的方法调配,一些C ++代码和宏来自动化和最小化一些编码。

首先是测量时间的简单C ++类

class PerfTimer
{    
public:
    PerfTimer(PerfProfiledDataCounter* perfProfiledDataCounter);
    ~PerfTimer();

private:
    uint64_t _startTime;

    PerfProfiledDataCounter* _perfProfiledDataCounter;
};

我正在使用C ++来表示当对象退出当前范围时将执行析构函数。我们的想法是在每个混合方法的开头创建PerfTimer,它将负责测量此方法的运行时间

PerfProfiledDataCounter是一个简单的结构,它计算执行次数和整个已用时间(因此它可以找出平均花费的时间)。

此外,我正在为每个我想要的配置文件创建一个名为“__Performance_Profiler_Category”的类别,并且符合“__Performance_Profiler_Marker”协议。为了更容易创建,我使用了一些自动创建此类别的宏。我还有一组宏,它们采用选择器名称,返回类型和参数类型,并为每个选择器名称创建选择器。

对于上述所有任务,我创建了一组宏来帮助我。此外,我有一个扩展名为.mm的文件,用于注册我想要分析的所有类和所有选择器。在应用程序启动时,我使用运行时来检索符合“__Performance_Profiler_Marker”协议(即已注册的)协议的所有类,并搜索标记为分析的选择器(这些选择器以预定义的前缀开始)。请注意,此.mm文件是唯一需要.mm扩展名的文件,并且无需为我要分析的每个类更改文件扩展名。

之后,代码使用已分析的代码调整原始选择器。在每个配置文件中,我只创建PerfTimer并调用swizzled方法。

简而言之,这是我的想法,结果非常顺利。