Very High CPU usage when downloading data

JuanjoAJuanjoA ESMember ✭✭

Hello, some users of my application warned me about a really high CPU usage when downloading large files. I investigated and found that the network operations using WebClient or HttpWebRequest are using all the CPU.

This is more noticiable when downloading large files, but the CPU usage is always high for any downloads.

Here is a simple test case:

    byte[] buffer = new byte[4096];
        using (WebClient wc=new WebClient())
        {
            WebRequest wr = WebRequest.Create("http://cdimage.ubuntu.com/releases/18.04.2/release/ubuntu-18.04.2-server-amd64.iso");
            WebResponse wresp = wr.GetResponse();
            using (var respstream = wresp.GetResponseStream())
            {
                int readed = 0;
                do
                {
                    readed = respstream.Read(buffer, 0, 4096);
                }
                while (readed > 0);
            }
        }

This code uses the 100% of the CPU on Xamarin.Mac but uses less than 1% of the CPU on Windows

This other simple code uses around 70% of the CPU on Xamarin.Mac and less than 1% on Windows

using (WebClient wc=new WebClient())
{
    wc.DownloadFileAsync(new Uri("http://cdimage.ubuntu.com/releases/18.04.2/release/ubuntu-18.04.2-server-amd64.iso"), "/Users/myuser/saved.iso");
}

I am using Visual Studio for Mac 8.1.3 with Xamarin.Mac 5.10.0.157

Can someone confirm the issue so we can see if it is a Xamarin.Mac problem?

Does anybody know of any workaround?

Posts

  • ChrisHamonsChrisHamons USForum Administrator, Xamarin Team Xamurai

    Maybe try comparing this to using HttpClient, specially with NSUrlSession session configured?

    I suspect that the WebClient API is not exceptionally performant in comparison.

  • JuanjoAJuanjoA ESMember ✭✭

    Thank you, I tried this code with HttpClient:

    private async void Download()
        {
            byte[] buffer = new byte[4096];
            using (HttpClient client = new HttpClient())
            {
                using (HttpResponseMessage response = await client.GetAsync(new Uri("http://cdimage.ubuntu.com/releases/18.04.2/release/ubuntu-18.04.2-server-amd64.iso")))
                {
                    using (Stream st = await response.Content.ReadAsStreamAsync())
                    {
                        int readed = 0;
                        do
                        {
                            readed = st.Read(buffer, 0, 4096);
                        }
                        while (readed > 0);
                    }
                }
            }
        }
    

    With NSUrlSession session configured it uses around 40-50% of the CPU. It is better, but it is still really high compared to Windows (less than 1% CPU)

    The higher the download speed the more CPU it uses.

    Actually I can not find a way to download a large file (several GB) with Xamarin.Mac without eating ~50% of my users CPU during the time that the download lasts (maybe hours).

  • Can you try CPU Optimization?

  • ChrisHamonsChrisHamons USForum Administrator, Xamarin Team Xamurai

    This forum post prompted an issue to be filed:

    https://github.com/xamarin/xamarin-macios/issues/6502

    which lead to a runtime issue:

    https://github.com/mono/mono/issues/15583

    which has a long explanation and some buffer size changes that can change performance characteristics.

Sign In or Register to comment.