Objective c 在多线程应用程序上测量AFN网络的响应时间
更新 经过一些研究,我对代码做了一些改进。我首先用以下方法替换我测量时间的每个位置:Objective c 在多线程应用程序上测量AFN网络的响应时间,objective-c,multithreading,afnetworking,load-testing,Objective C,Multithreading,Afnetworking,Load Testing,更新 经过一些研究,我对代码做了一些改进。我首先用以下方法替换我测量时间的每个位置:[NSNumber numberWithDouble:[[NSDate date]TimeIntervalsIncess1970]具有原子时间测量,例如:CFAbsoluteTimeGetCurrent() 我注意到这没什么区别。与我们的服务器人员核对时,我注意到服务器显示了令人印象深刻的结果——这让我觉得这里的瓶颈不是服务器,而是我的笔记本电脑/其他方面 原创帖子 我正在尝试对我的服务器进行负载测试,因此我构
[NSNumber numberWithDouble:[[NSDate date]TimeIntervalsIncess1970]代码>具有原子时间测量,例如:CFAbsoluteTimeGetCurrent()代码>
我注意到这没什么区别。与我们的服务器人员核对时,我注意到服务器显示了令人印象深刻的结果——这让我觉得这里的瓶颈不是服务器,而是我的笔记本电脑/其他方面
原创帖子
我正在尝试对我的服务器进行负载测试,因此我构建了一个模拟应用程序中用户流的场景。此流包含对服务器的大约11-17个调用,其中一些调用必须是同步的(因为用户除非通过其他屏幕,否则无法到达某个屏幕)
然后,我同时使用X
线程运行了这个场景,试图对服务器施加压力,看看最薄弱的环节在哪里。为了分析这些信息,每次回复(无论是成功还是失败)时,我都会将一些相关信息记录到一个文件中,并注意到每次调用的时间安排都有一些非常奇怪的事情发生
要测量通话时间,我在每次通话开始前使用以下方法测量了通话的开始时间:
test.startTime = [NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]];
//fire the request
[operation start];
在成功/失败模块中发生的第一件事是:
成功
void (^successWrapper) (AFHTTPRequestOperation *, id) = ^(AFHTTPRequestOperation *operation, id responseObject){
//#################TEST ANALYTICS###############
NSDate *endTime = [NSDate date];
test.endTime = [NSNumber numberWithDouble:[endTime timeIntervalSince1970]];
test.lat = [NSNumber numberWithDouble:(test.endTime.doubleValue - test.startTime.doubleValue)];
//##############################################
//Some other success stuff...
};
失败:
void (^failureWrapper) (AFHTTPRequestOperation *, NSError *) = ^(AFHTTPRequestOperation *operation, NSError *error) {
//#################TEST ANALYTICS###############
NSDate *endTime = [NSDate date];
test.endTime = [NSNumber numberWithDouble:[endTime timeIntervalSince1970]];
test.lat = [NSNumber numberWithDouble:(test.endTime.doubleValue - test.startTime.doubleValue)];
//##############################################
//Some other failure stuff...
};
然而,我在日志文件中遇到了非常高的延迟,并且随着X
越来越大,延迟变得越来越严重
我假设这个问题是由于线程之间的上下文切换造成的,但我不确定。因此,我的问题是:在一个具有多线程的系统中,如何正确测量AFNetworking
中每个调用的响应时间
一些注意事项:
- 如上所述,一些调用可以同时发生,而另一些调用必须按顺序发生
X
最终应该非常高(>10000)
谢谢 可以同时运行的NSURLConnection
网络请求数量有限。您可以启动任意数量的操作,但是NSURLConnection
只能同时运行有限数量的操作(我相信是4-6次,取决于操作系统版本)。后续的NSURLConnection
请求将等待前面的请求完成。在极端情况下(例如提交数百个请求),这甚至会导致后一个请求超时(除非指定足够大的超时参数)。这个约束不是网络延迟,而是操作系统对客户端施加的有限数量的并发请求的产物
在客户端应用程序中,当使用基于NSOperationQueue
的框架(如AFNetworking)时,您不需要自己启动操作,只需将操作添加到NSOperationQueue
即可解决此限制。然后,您可以将操作队列的maxConcurrentOperationCount
限制为某个合理的数量,该数量对应于可在任何给定时间运行的并发NSURLConnection
请求的数量(例如,我可能建议5),以消除单个操作中出现的延迟。如果要将这些请求添加到自己的队列中,则需要为该队列指定maxConcurrentOperationCount
。如果您使用的是afhttprequestorerationmanager
,则应该在管理器的operationQueue
属性上执行此操作
如果您想在上述上下文中对AFNetworking的性能进行基准测试,问题是您是否希望测量总运行时间(在这种情况下,您可以在将开始时间添加到队列中时捕获开始时间,然后在完成块中计算运行时间,类似于您在问题中概述的方式)或者您是否希望捕获实际运行操作所花费的时间
如果您对后者感兴趣,您确实希望在操作队列导致调用start
方法时启动计时器,您可以为AFNetworkingOperationDidStartNotification
和AFNetworkingOperationDidFinishNotification
通知添加观察员,或者只需拨叉AFNetworking并修改AFURLConnectionOperation
即可计算所用时间
最后,有点不清楚你的问题是真的对应用程序进行压力测试,还是对服务器进行压力测试。如果只是简单地对应用程序进行压力测试,上述方法应该可以奏效。如果您想对服务器进行压力测试以模拟多个同时使用的用户,这将更加困难,并且可能需要完全绕过NSURLConnection
/AFNetworking(使用CFNetwork
)或者真的设置一组物理设备/计算机,让它们同时进行客户端AFNetworking压力测试。在10000个线程时,您将看到巨大的开销,我建议将您的测试应用程序限制在少数几个线程内。@SamMiller,好吧-我有100个线程(甚至更少),不要说10000…@goldengil,你应该使用<20个线程,而不是大约100个。