object-c编程tips-global_queue的一个小测试

前一段进行网络基础库构建的时候,网络发送的加密组包以及网络返回的回调解包处理都是在单独的主线程处理。 跟踪程序的时间发现这部分耗时还挺大,于是决定使用多线程处理,至少不应该使用主线程。

一直以来网上都在强调多线程的dispatch的妙用,自己仅仅是会用而没有实际测试过它的性能。今天将上次测试的结果发出来,说实话dispatch的多线程效率确实很高,跟cpu的核心数有很多关系。

测试思想:

使用一个自己写的耗时函数,让其执行一次所需要的时间进行记录。然后使用dispatch_global_queue进行执行4,6,8,10遍所耗的时间进行记录,来得到所花费的时间。基本代码非常简单,如下:

//
//  main.m
//  ThreadTest
//
//  Created by lipeng on 14-7-23.
//  Copyright (c) 2014年 com.hollance. All rights reserved.
//

#import <Foundation/Foundation.h>
#include <sys/time.h>

#define REPEAT_TIMES 6
/*
 可以看出自己的电脑的是几核的。
 按道理说重复四次应该是4倍的时间,但是由于是双核的cpu,因此只需要两倍的时间。
 */

typedef void*(*workFunc)(void) ;
#define SetFunc(func) #func, (workFunc)func

int getTime(char* identify, workFunc func)
{
    struct timeval tv_begin, tv_end, tv_diff;
    gettimeofday(&tv_begin, NULL);

    func();

    gettimeofday(&tv_end, NULL);
    timersub(&tv_end, &tv_begin, &tv_diff);
    long timeCost = tv_diff.tv_sec*1000 + tv_diff.tv_usec/1000;
    printf("%20s cost %10ld millseconds\n", identify, timeCost);

    return 0;
}
int costTimeFunc()
{
    double m = 1.2, j = 3.4, k = 5.87;
    for (int i = 0; i < 3*3000000; ++i) {
        j = m * k * m;
        k = m * j * k;
        m = k * j * k;
        k = i * j * m;
    }
    return 0;
}
void testOneThread()
{
    costTimeFunc();
}
void testTwoThread()
{
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_sync(globalQueue, ^{
        dispatch_apply(REPEAT_TIMES, globalQueue, ^(size_t index) {
            costTimeFunc();
        });
    });
}
int main(int argc, const char * argv[])
{
    @autoreleasepool {
        for (int i = 0; i < 10; ++i) {
            getTime(SetFunc(testOneThread));
            getTime(SetFunc(testTwoThread));
        }
    }
    return 0;
}

通过修改#define的 Repeat_times可以测试重复不同次数所花费的时间。测试结果发现当cpu是双核的时候,基本上时间会减少一半,cpu是四核的时候,时间大约是1/4。不过在i5双核上时间也是1/4,这是因为i5是双核四线程的,每一个核心可以同时两个线程在跑。这也间接印证了dispatch_global_queue的效率之高。

因此对于网络请求的处理还是采用dispatch_global_queue比较好,这样既避免了主线程的阻塞,同时对于多个同时发送的请求的返回处理效率会提高一些。在request的返回回调中首先用global_queue对结果进行预处理,拆包,解密,解析成数据model,然后将最后解析完地内容dispatch给主线程就OK了。通过这样的方式,主线程仅仅关心自己的界面逻辑处理,将它从繁重的数据解析工作中解脱了出来,提升了效率。

object-c编程tips-global_queue的一个小测试

时间: 2024-10-22 06:03:18

object-c编程tips-global_queue的一个小测试的相关文章

[UNet]通过一个小测试了解Command和ClientRpc的功能

作者只是业余时间接触Unity 2个月的新人一枚,如有不对的地方,请各位大神指正! Unity 5.以后使用了新的网络模块UNet(其实我接触的晚压根没用过老的- -!),但是在使用过程中确实关于UNet的资料和讨论挺少的,于是自己做了个小项目测试了Command和ClientRpc两个命令. 首先我们看看官方给出的定义: Commands Commands are sent from player objects on the client to player objects on the s

字符串的一个小测试

字符串即若干字符组成的序列,每个字符串都以'\0'结尾,由于这个特点,每个字符串都有一个额外的字符开销,所以要注意字符串越界的问题. 如: char str[10]; strcpy(str,"0123456789");//越界 同时,很多函数如strcpy.strlen.strcmp.strstr等字符串函数都是用了这个特点实现. 为节省内存,c和c++把常量字符串放到了静态区,当几个指针赋值给相同的的字符串常量时,它们会指向相同的地址.但用常量初始化数组则不同 char a1[]=&

关于cout的一个小测试

以前知道使用cout<<endl换行会刷新缓冲区,但是从来也没在意过这个问题,早上起来翻书看到关于这方面的东西就来做了个测试,不做不知道,一测下一跳啊- -! 测试代码: /** 吉林大学 Jilin U Author: sinianluoye (JLU_LiChuang) Date: 2015-3 Usage: **/ #include <iostream> #include <cstdio> #include <cstring> #include <

Python下实现文件中的全文搜索小测试

username = 'test' password = '123456' while True: user_str = raw_input("Please input your name>>") pass_str = raw_input("Please input your password>>") if username != user_str or password != pass_str: print "Sorry,You 

记一个小错误:&#39;numpy.ndarray&#39; object is not callable

错误在于mfcc是已经定义的函数,所以变量名改为wav_mfcc,问题就解决了. 参考博客: https://blog.csdn.net/Olaking/article/details/43199003 记一个小错误:'numpy.ndarray' object is not callable 原文地址:https://www.cnblogs.com/yuren1998/p/11558700.html

基于委托的C#异步编程的一个小例子 带有回调函数的例子

我创建的是一个winform测试项目:界面如下: 设置: 下面是代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; usin

Java编程Tips

原文: Java编程中"为了性能"尽量要做到的一些地方 作者: javatgo 最近的机器内存又爆满了,除了新增机器内存外,还应该好好review一下我们的代码,有很多代码编写过于随意化,这些不好的习惯或对程序语言的不了解是应该好好打压打压了. 下面是参考网络资源总结的一些在Java编程中尽可能要做到的一些地方. 1. 尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面: 控制资源的使

[Object]面向对象编程(高程版)(0)属性和方法

[Object]面向对象编程(高程版)(0)属性和方法 博客分类: Web前端-JS语言核心 私有变量成员变量公有变量静态变量 zccst转载+原创 Js代码   function Person(){ var private_name = "小明"; //私有属性 var private_age = 10;      //私有属性 this.privilege_name = "小红"; //特权属性 this.privilege_age = 9;       //特

object-c编程tips

如何写一个对扩展开发对修改关闭的推送消息处理中心? 前一段时间做的推送消息处理,总是要根据不同的消息类型,进入到不同的消息处理流程中.由于消息处理流程的总体框架大同小异,只是具体的很小的一块代码不同. 于是很容易想到使用模板方法模式基类写框架流程,派生类负责具体的实现. 需要有三个类: LPPushDispatchCenter: 消息处理中心类 LPPushDispatch :消息处理基类 LPDetailPushDispatch(很多很多个这样的派生类): 消息处理派生类 所有的消息首先进入消