2010-06-02 51 views
0

我试图拼凑在一起,并运行一个由用户放在一起的任务列表。这些任务列表可能长达数百或数千个项目。msg_send调用会产生多少开销?

据我所知,最简单,最明显的办法是建立一个数组,然后遍历它们:

NSArray *arrayOfTasks = .... init and fill with thousands of tasks 

for (id *eachTask in arrayOfTasks) 
{ 
    if (eachTask && [eachTask respondsToSelector:@selector(execute)]) [eachTask execute]; 
} 

对于台式机,这可能是没有问题的,但在iPhone或iPad这可能是一个问题。这是一个好方法吗?还是有更快的方法来完成同样的事情?

我之所以问msg_send发生了多少开销,是因为我也可以做一个直接的C实现。例如,我可以放置一个链表并使用一个块来处理下一个任务。我会从中得到什么,或者比它的价值更麻烦吗?

+1

您不需要检查'eachTask'是否为非零。如果'eachTask'为零,或者它不响应'execute','respondsToSelector:'将导致NO。 – dreamlax 2010-06-03 07:49:39

+2

无论如何,你不会从NSArray中获得“无”值。 – kperryua 2010-06-03 14:57:36

+2

'id *'在这里写错了 – newacct 2012-09-17 22:26:59

回答

6

我假设你在谈论objc_msgSend,在这种情况下,Bill Bumgarner拥有非常棒的 4 Part Series值得一读。

一般来说,我会推荐使用Obj-C。这就是iDevices使用的所有应用程序(包括Apple)以及数百个项目都不会杀死该设备。

+0

+1好文章 – shosti 2010-06-03 03:39:03

+0

谢谢!伟大的文章! – pxl 2010-06-03 07:40:25

+0

只是我评论的附录......我喜欢深入了解事物的内容,而且苹果的文档只做到目前为止...所以这真的是一篇很棒的文章! – pxl 2010-06-03 07:45:41

0

rynmrtn说什么......

除非你-execute方法是非常简单的 - 递增/测试标量值的极少数 - 那么它是不可能的,即使objc_msgSend()将显示为你的程序的% CPU时间。

先测量后优化。

您的代码确实提出了一个问题;为什么你把东西放进arrayOfTasks,可能无法使用execute。假设您的arrayOfTasks中的所有内容都是您制作的子类,则可以添加execute方法,而不要执行响应测试。如果你有一个集合类的层次结构,你可以使用类别来添加方法 - 只要在他们的前面加上一个前缀来保证安全(即pxl_execute或其他)。

+0

我可能应该使用伪代码,但想法是通过数千个对象的列表,并调用每个对象的方法 – pxl 2010-06-03 07:42:27

0

Here是一个很好的基准比较常用操作,包括objc_msgSend。一般来说,即使在iPhone上,您也不必担心其性能。消息发送总是比直接的C函数调用慢,但在现代处理器上(请记住,iPhone处理器仍然大约为500 mhz),但大多数情况下这种差异是微不足道的。如果剖析显示在objc_msgSend中正在使用大量时间,则可能值得使用直接C函数而不是Objective-C方法。

为了清楚起见,您可以使用-[NSArray makeObjectsPerformSelector:]或(在Mac上)enumerateObjectsUsingBlock:而不是遍历对象,但我认为它不会带来太多的性能差异。

+0

谢谢!从评论和我自己阅读的内容来看,我真的不应该太担心objc_msgSend,而只是想出一些有用的东西。然后,像你所建议的那样,运行性能基准测试并开始找出所有瓶颈和缓慢点。 – pxl 2010-06-03 07:44:14

相关问题