在AFNetworking HTTP GET中测量响应时间 [英] Measuring response time in AFNetworking HTTP GET

查看:137
本文介绍了在AFNetworking HTTP GET中测量响应时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用AFNetworking下载文件时,我正在尝试测量每个GET请求所花费的时间。我反复循环下载文件。
我遇到的问题是我测量总时间的方式,它提供的总时间比实际多得多。例如,对于50次下载,它给出了72秒,但实际上仅花费了大约5秒。我还怀疑5秒对于50次下载来说太低了(每个文件的下载大小为581 kb)。

I am trying to measure time taken per GET request when downloading a file using AFNetworking. I am downloading a file repeatedly in a loop. The problem I am having is that the way I am measuring total time, it gives a much larger total time than it actually is. For example, for 50 downloads it gives 72 sec but in reality it only took around 5 sec. I also suspect 5 sec is too low for 50 downloads(the download size is 581 kb per file).

在这种情况下,如何有效地测量时间?从发出请求到收到响应,我需要时间。

How do I effectively measure time in this case? I need time from the moment request is fired till response in received.

我下载文件的方法:

- (void) HTTPGetRequest
{    
    startTime = CACurrentMediaTime(); // Start measuring time

    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:http://myServer];
    NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET"
                                                            path:@"/download/Text581KB.txt"
                                                      parameters:nil];
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    [httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];

    // Save downloaded file
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"Text581KB.txt"]];
    operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        double elapsedTime = (CACurrentMediaTime() - startTime); // Measuring time
        totalTime += elapsedTime; // Measuring total time HERE!
        [results setString:[NSString stringWithFormat: @"Current Transaction Time: %f sec\nTotal Time: %f sec", elapsedTime, totalTime]];
        [_resultLabel performSelectorOnMainThread:@selector(setText:) withObject:results waitUntilDone:NO];
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];

    [operation setDownloadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {  ((int)totalBytesExpectedToWrite));
        totalDownloadSize += totalBytesExpectedToWrite;
        [_DataTransferredLabel setText:[NSString stringWithFormat:@"Total Download Size: %@", [self getFileSize:totalDownloadSize/1024]]];
    }];

    [operation setCacheResponseBlock:^NSCachedURLResponse *(NSURLConnection *connection, NSCachedURLResponse *cachedResponse) {
        return nil;
    }];
    [operationQueue addOperation:operation];
}

我正在viewDidLoad中创建NSOperationQueue:

I am creating a NSOperationQueue in my viewDidLoad:

operationQueue = [NSOperationQueue new];
[operationQueue setMaxConcurrentOperationCount:1]; // using this as I was suspecting downloads were happening in parallel & thus 50 downloads finishing in a few secs

我正在按以下方式调用HTTPGetRequest方法:

I am invoking the HTTPGetRequest method as follows:

- (IBAction)startDownload:(UIButton *)sender {
    totalCount = [[_countText text] longLongValue]; // get # of times to download
    long currentCount = 1;
    completedCount = 0;
    totalTime = 0;
    totalDownloadSize = 0;
    while (currentCount <= totalCount)
    {
        [self HTTPGetRequest];
        [results setString:@""];
        currentCount++;

    }


推荐答案

在计算累计时间(而不是经过时间)时,我刚刚创建了一个 AFHTTPRequestOperation 子类来捕获开始时间。否则,您将无法确切知道它的开始时间:

In terms of calculating cumulative time (not elapsed time), I have just created a subclass of AFHTTPRequestOperation that captures the start time. Otherwise, you won't know precisely when it started:

@interface TimedAFHTTPRequestOperation : AFHTTPRequestOperation

@property (nonatomic) CFAbsoluteTime startTime;

@end

@implementation TimedAFHTTPRequestOperation

- (void)start
{
    self.startTime = CFAbsoluteTimeGetCurrent();

    [super start];
}

@end

(请注意,我正在使用 CFAbsoluteTimeGetCurrent CACurrentMediaTime ;使用您想要的任何内容,但要保持一致。)

(Note I'm using CFAbsoluteTimeGetCurrent versus CACurrentMediaTime; use whatever you want, but just be consistent.)

然后在进行下载的代码中,可以使用此 TimedAFHTTPRequestOperation 代替 AFHTTPRequestOperation

Then in the code that's doing the downloads, you can use this TimedAFHTTPRequestOperation instead of AFHTTPRequestOperation:

TimedAFHTTPRequestOperation *operation = [[TimedAFHTTPRequestOperation alloc] initWithRequest:request];

该代码的完成块可以使用 startTime TimedAFHTTPRequestOperation 的>属性,以计算给定操作经过的时间并将其添加到总时间中:

That code's completion block can then use the startTime property of TimedAFHTTPRequestOperation to calculate the time elapsed for the given operation and add it to the total time:

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    TimedAFHTTPRequestOperation *timedOperation = (id)operation;
    CFTimeInterval elapsedTime = CFAbsoluteTimeGetCurrent() - timedOperation.startTime;
    self.totalTime += elapsedTime; // Measuring total time HERE!
    NSLog(@"finished in %.1f", elapsedTime);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

这就是计算 elapsedTime 并追加的方式他们一起计算 totalTime

That's how you calculate the elapsedTime and append them together to calculate the totalTime.

关于如何知道何时完成操作,我会

In terms of how to know when the operations are done, I would


  • 修改 HTTPGetRequest 以返回 NSOperation ;

具有 startDownload 创建完成操作,然后添加所有这些操作作为依赖项的操作:

have startDownload create a completion operation and then add all of these operations as dependencies:

NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"finished all in cumulative time: %.1f", self.totalTime);
}];

for (NSInteger i = 0; i < totalCount; i++)
{
    NSOperation *operation = [self HTTPGetRequest];
    [completionOperation addDependency:operation];
}
[self.operationQueue addOperation:completionOperation];


这实现了几个目标,即创建完成操作,计算总时间(而不是经过的总时间)。

That achieves several goals, namely creating a completion operation, calculating the total time (as opposed to the total time elapsed).

顺便说一句,我也建议取消创建您的 HTTPGetRequest 中的AFHTTPClient 。您可能应该只为每个应用创建一个。如果您曾经开始使用 enqueueHTTPRequestOperation 而不是创建自己的操作队列,这一点尤其重要。我也认为不需要调用 registerHTTPOperationClass

By the way, I'd also suggest pulling the creation of AFHTTPClient out of your HTTPGetRequest. You should probably only create one per app. This is especially important in case you ever started using enqueueHTTPRequestOperation instead of creating your own operation queue. I also see no need for your call to registerHTTPOperationClass.

您将 totalElapsed 增加了 lapsedTime ,但 elapsedTime 是从 startTime 计算,它本身代表作业第一次排队的时间,而不是实际开始下载的时间。请记住, HTTPGetRequest 几乎立即返回(已设置 elapsedTime )。因此,如果您要排队5次下载, HTTPGetRequest 会运行5次(并设置并重置 startTime 五次)甚至在第一个请求启动之前。

You are incrementing the totalElapsed by elapsedTime, but elapsedTime is calculated from startTime, which itself represents the time that the jobs were first queued, not when the download actually started. Remember that HTTPGetRequest returns almost immediately (having set elapsedTime). Thus if you're queueing five downloads, I wouldn't be surprised that HTTPGetRequest runs five times (and sets and resets startTime five times) before the first request even is initiated.

问题是,您是否正在进行并发下载,如果这样,那么会进一步使问题复杂化然后,您的意思是已用完。假设您有两次并发下载,一次下载需要5秒钟,另一次需要7秒钟。您是否希望答案为7(因为它们都在7秒内完成)?还是您希望答案是12(因为它们都在12秒钟内完成)?

The question is further complicated by the question of whether you're doing concurrent downloads, and if so, what you then mean by "total elapsed". Let's say you have two concurrent downloads, one that takes 5 seconds, another takes 7 seconds. Do you want the answer to be 7 (because they both finished in 7 seconds)? Or do you want the answer to be 12 (because they both finished in a cumulative 12 seconds)?

在这种情况下,我假设您正在寻找,即7秒,那么您应该在启动所有请求之前设置一次 startTime ,然后仅计算何时完成所有下载。例如,您可以根本不用在 HTTPGetRequest 中进行任何计算,而只是添加自己的操作,该操作取决于您添加的所有其他操作,从而计算出总耗用的时间。在最后。或者,如果您希望总经过时间仅反映下载过程中的总经过时间,则只需设置 totalElapsed 而不是增加它。

I'm presuming that you're looking for, in this scenario, 7 seconds, then you should set the startTime once before you initiate all of your requests, and then only calculate when all of the downloads are done. You could, for example, rather than doing any calculations in HTTPGetRequest at all, just add your own operation that is dependent upon all the other operations you added, which calculates the total elapsed. at the very end. Or, if you want the the total elapsed to just reflect the total elapsed while you're in the process of downloading, then just set totalElapsed rather than incrementing it.

这篇关于在AFNetworking HTTP GET中测量响应时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆