我们在衡量某项技术、开源组件的性能时经常会设计一些对比实验来做验证。这种对比实验就像田径比赛,几个人一起赛跑,谁跑得快就是冠军。我们开发的功能可以跑在不同的硬件条件的设备,一般我们会选择条件最差的设备,或者我们业务应该支持的最差设备来做实验。但软件功能所承载的业务场景通常也比较多变,就像一个运动员要跑100米、800米、3000米,设计单一的条件最后做出来的实验结果可能没有太大意义。比如做iOS多线程技术性能的对比实验时,如果这样设计初始条件“控制线程数为20个、1000次线程任务循环次数“,最终得到的实验结果对工程开发的指导意义就不够。不同业务场景条件差别其实很大,比如IM、位置实时更新、抢订单属于高频率、低任务耗时,而数据库等IO操作属于低频率、高任务耗时。所以我们需要归纳各种多线程场景,使用多因素设计,设计多个自变量。还是回到多线程性能实验的例子。自变量:线程数、任务耗时、任务数。自变量的条件要能覆盖常用的业务场景,线程数:5~15~30,任务数:1000~10000~100000,任务耗时:1~5~10毫秒。最终得出来的实验结果也可以较准确得命中各种实际使用场景。
iOS常用的多线程技术有NSThread、GCD、pthread、NSOperation几种技术。之前看过一些开发者对这几种技术做过实验测试,得出具体的数据比较。但仅仅统计一定数量级别的运行效率对实际应用没有太大的指导性意义,最好是能模拟实际场景的线程环境来做测试。
那不同场景的因子有什么呢?
并发频率高低、任务耗时长短、稳定性
对应的测试关注点是什么?
并发频率高低:统计多个线程并发运行,最后全部运行完成的耗时长短
任务耗时长短:统计单个线程里不同耗时任务的完成时间
稳定性:进行多次实验,统计数据的变动区间
分析出上面测试关注点后,我们可以开始来设计实验了。
实验对象:
NSThread、单队列并行GCD、多队列串行GCD、NSOperation、pthread
实验环境:
设备、编译环境
实验变量:
线程的数量、每个线程里执行的任务次数、每个任务的耗时长短
实验方法:
模拟实际场景,设置几组实验变量的搭配,比如下面几组。
线程数:5/15个
任务数:1000/10000/100000次
耗时:1/5/10 毫秒
实验结果:
任务平均耗时速度排名
NSOperation > 多队列串行GCD/NSThread > 单队列并行GCD
所有线程任务全部完成速度排名
多队列串行GCD/NSThread > NSOperation/单队列并行GCD
实验结论
多队列串行GCD和NSThread的特点相似,多个线程高并发的完成速度最快,单个线程的执行性能中等。
所以这两种技术适合高频率、低任务耗时的应用场景,比如IM、位置更新、抢订单等实时消息通信场景
NSOperation的特点是单个线程的执行性能最快,所以适合低频率、高任务耗时的应用场景,比如数据库、文件等IO场景