单个 URLSession 适用于所有请求与每个请求、性能

Single URLSession for all requests versus per request, performance

提问人:Devarshi 提问时间:10/23/2023 更新时间:10/23/2023 访问量:26

问:

在一个同时具有 ObjC 和 Swift 代码的遗留项目中,我注意到为每个请求创建了一个新会话:

-(void)sendRequest {
// Some configuration

// New session is created for every request
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:nil delegateQueue:[NSOperationQueue mainQueue]];
[session dataTaskWithRequest:self.request completionHandler:^(NSData * _Nullable data, NSURLResponse *_Nullable response, NSError * _Nullable error) {
// Doing something with response
}
}

根据过去WWDC视频中共享的信息,并在这里回答:New NSURLSession for every DataTask over-kill?,我注意到这是一个反模式,应该避免。在它的位置,我们应该对所有请求使用一个 URLSession:

-(void)sendRequest:(NSURLReqest *)request {
// Some configuration

// 
[self.session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse *_Nullable response, NSError * _Nullable error) {
// Doing something with response
}
}

请注意,在服务器上,HTTP 1.1 是为 rest API 配置的。

根据我的理解,每当我们创建一个新会话时,它就等同于创建一个新的 TCP 连接,因为每个新的 TCP 连接在开始时都会涉及握手,这会增加延迟,因此理想情况下,我们应该为每个请求使用相同的 URLSession。

为了验证它,我开始使用 Instruments 分析这两种实现,在登录后,我们调用了 50 个 API,其中大多数返回 json 作为响应,10 个返回图像数据。

这是我的观察:

  1. 每个请求所花费的时间略有改善
  2. 每当我们对每个请求使用一个会话时,操作系统都会在内部创建并行连接,因此与用于所有请求的单个会话相比,它实现了相同的结果
  3. 如果我们使用 URLSessionDataTask 直接序列化图像,则与使用 URLSessionDownloadTask 相比,它花费的时间更少

根据第 2 次和第 3 次观察,就我而言,这似乎是一个糟糕的选择。我在这里错过了什么吗?

Objective-C 性能 URLSession

评论

0赞 Larme 10/24/2023
如果并行启动过多调用,则可能会过度使用资源,因为可能会创建过多的线程。使用单个 URLSession 时,您可以限制并行调用(例如,使用 )。httpMaximumConnectionsPerHost
0赞 Devarshi 11/23/2023
@Larme不幸的是,除非是绩效上的胜利,否则很难说服利益相关者。
0赞 Larme 11/23/2023
对超过 10 个请求(如 100 个)在真实设备上进行测试。如果可能的话,在“旧”上也是如此。你可能会看到差异。

答: 暂无答案