【问题标题】:Xamarin - Multiple HTTP Requests slow down the appXamarin - 多个 HTTP 请求会减慢应用程序的速度
【发布时间】:2014-05-23 08:15:10
【问题描述】:

我正在使用 Xamarin 开发 iOS 应用。其中一项功能是以 hls 格式下载视频,这意味着每个视频可以有 100 到 1000 个块可供下载。所以我需要做 100 到 1000 个 http 请求。这是可行的,但下载时应用程序非常慢,我使用“仪器”进行了性能测试,CPU 为 80%,完成后又回到 0%-1%。这是在 ipad 上测试,不是在模拟器上。

public async Task CreateDownloadTask (string path){

var response = await _httpClient.GetAsync (GetUrl(path),
                                     HttpCompletionOption.ResponseHeadersRead);

if (!response.IsSuccessStatusCode) 
{
    Debug.WriteLine ("Error: " + path);
    RaiseFault(new RpcFault("Error: Unable to download video", -1));
} 
else 
{
    var totalBytes = response.Content.Headers.ContentLength.HasValue 
                   ? response.Content.Headers.ContentLength.Value : -1L;

    using (var stream = await response.Content.ReadAsStreamAsync ()) 
    {
        var isMoreToRead = true;
        var data = new byte[totalBytes];

        do 
        {
            _cancelSource.Token.ThrowIfCancellationRequested ();
            var buffer = new byte[4096];
            int read = stream.ReadAsync(buffer, 
                                        0, 
                                        buffer.Length,
                                        _cancelSource.Token).Result;

            if (read == 0)
                isMoreToRead = false;
            else {
                buffer.ToList ().CopyTo (0, data, receivedBytes, read);
                receivedBytes += read;
                HlsVideo.TotalReceived += read;
            }
        } while(isMoreToRead);

        var fullPath = GetFullFilePath (path);
        _fileStore.WriteFile (fullPath, data);
    }
}

在执行多个 http 请求时如何提高性能?

【问题讨论】:

  • 当您在缓冲区上调用ToList() 时?首先,这引入了不必要的复制。为什么要在while 循环的每次迭代中创建一个新缓冲区?只需在循环之前创建它一次,这样您就可以继续重用同一个缓冲区。事实上,你为什么有buffer?您已经有效地获得了一个缓冲区 - data。直接阅读:int read = stream.ReadAsync(data, receivedBytes, totalBytes - receivedBytes, _cancelSource.Token).Result;
  • 你是对的!我删除了缓冲区,它似乎工作得更好。它减少了大约 20% 的 CPU 使用量!滚动项目列表时仍然不流畅,因此欢迎提供更多提示。谢谢!
  • 您是否有任何理由使用同步调用WriteFile?这也可能让它变得生涩......
  • 太棒了!好多了,我现在异步调用 writeFile,它提高了性能!谢谢
  • 好的 - 会写下来作为答案。

标签: c# ios http xamarin httprequest


【解决方案1】:

目前的代码有两个很多问题:

  • 在读取数据方面效率低下
  • 它是同步写入数据,如果你在UI线程上,这显然是个问题

“异步写入数据”可能是一个更简单的解决方法,那么我们来看看读取数据的效率低下:

  • 您在每次迭代中分配buffer。我们不关心上一次迭代的数据,所以你可以在while循环之前分配一次
  • 您在 buffer 上调用 ToList,这将制作一个副本 - 然后您将其复制到 data
  • 您实际上根本不需要buffer!您可以将字节直接读入data,而不是每次迭代中的两个分配和两个副本:

    var data = new byte[totalBytes];
    
    do {
        _cancelSource.Token.ThrowIfCancellationRequested ();
        int read = stream.ReadAsync(data, receivedBytes, data.Length - receivedBytes, 
                                    _cancelSource.Token).Result;
    
        receivedBytes += read;
        if (read == 0 || receivedBytes == data.Length)
            isMoreToRead = false;
        }
        HlsVideo.TotalReceived += read;
    } while(isMoreToRead);
    // TODO: check that receivedBytes == data.Length!
    

【讨论】:

    猜你喜欢
    • 2017-10-11
    • 1970-01-01
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    相关资源
    最近更新 更多