测量响应时间AFNetworking HTTP GET(Measuring response tim

2019-10-29 04:15发布

我试图测量下载使用AFNetworking文件时每GET请求所用的时间。 我在一个循环中重复下载的文件。 我遇到的问题是,我测量总时间的方式,它比它实际上是一个更大的总时间。 例如,对于50个下载它给了72秒,但实际上只用了约5秒。 我还怀疑5秒太低50个下载(下载大小为每个文件581 KB)。

如何有效地测量在这种情况下一次? 我需要时间的那一刻起请求被解雇,直到响应中收到的。

我的方法来下载文件:

- (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:

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方法如下:

- (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++;

    }

Answer 1:

在计算累计时间(不经过时间)方面,我刚刚创建的子类AFHTTPRequestOperation捕获的开始时间。 否则,你将不能准确地知道什么时候开始:

@interface TimedAFHTTPRequestOperation : AFHTTPRequestOperation

@property (nonatomic) CFAbsoluteTime startTime;

@end

@implementation TimedAFHTTPRequestOperation

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

    [super start];
}

@end

(请注意我用CFAbsoluteTimeGetCurrentCACurrentMediaTime ;无论你想使用,但仅仅是一致的。)

然后在做这下载的代码,你可以使用这个TimedAFHTTPRequestOperation代替AFHTTPRequestOperation

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

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

[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

在如何认识而言,当操作完成后,我会

  • 修改HTTPGetRequest到返回NSOperation ;

  • startDownload创建完成操作,然后添加所有这些操作的依赖关系:

     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]; 

这几个实现的目标,即创造一个完成的操作,计算总时间(相对于过去的总时间)。

顺便说一句,我也建议拉的创建AFHTTPClient出你的HTTPGetRequest 。 你或许应该只创建一个每个应用程序。 这是尤其重要,你曾经使用开始enqueueHTTPRequestOperation ,而不是创建自己的操作队列。 我也认为没有必要为您的来电registerHTTPOperationClass


您正在递增totalElapsedelapsedTime ,但elapsedTime从计算startTime ,这本身就代表了工作岗位第一个排队,不会因下载实际开始的时间。 请记住, HTTPGetRequest返回几乎立即(将其具有elapsedTime )。 因此,如果你正在排队5次下载,我就不是很惊讶HTTPGetRequest运行5次(设定并重置startTime甚至已开始的第一个请求前五次)。

现在的问题是是否你正在做的并发下载的问题进一步复杂化,如果是这样,你再由意味着“总运行”。 比方说,你有两个并发下载,即需要5秒,另一个需要7秒。 你想要的答案是7(因为它们都在7秒内完成)? 或者你想要的答案是12(因为它们都以累积12秒结束)?

我假定你正在寻找的,在这种情况下,7秒,那么你应该设置的startTime ,一旦你开始你所有的请求之前,然后只有当所有下载完成计算。 你可以,例如,而不是在做任何计算HTTPGetRequest所有,只是添加自己的操作,取决于你所添加的,它经过计算总的其他操作。 在最后。 或者,如果你想要的总流逝恰恰反映当你在下载的过程中是经过总,然后只设置totalElapsed而不是增加了。



Answer 2:

使用AFHTTPRequestOperationLogger 。



Answer 3:

另一种选择是通过观察AFNetworkingOperationDidStartNotification通知注入在操作的用户信息“火”的日期。

//AFHTTPRequestOperation *operation = [...]
id __block observer = [[NSNotificationCenter defaultCenter] addObserverForName:AFNetworkingOperationDidStartNotification
        object:operation
         queue:nil
    usingBlock:^(NSNotification *note) {
                   operation.userInfo = @{@"fireDate": [NSDate date]};
                   [[NSNotificationCenter defaultCenter] removeObserver:observer];
              }];


文章来源: Measuring response time in AFNetworking HTTP GET