uno icon indicating copy to clipboard operation
uno copied to clipboard

[skia macOS] File.ReadAllLinesAsync in Debug takes a huge amount of time

Open ArchieCoder opened this issue 1 year ago • 8 comments

Current behavior

For a text file of 50 mb, it takes about 30 seconds to execute File.ReadAllLinesAsync in Debug and Skia macOS only.

This is possibly a regression since I haven't seen this before.

Expected behavior

As fast as release or other platforms.

How to reproduce it (as minimally and precisely as possible)

Open UnoScottApp.zip

Put a break point before File.ReadAllLinesAsync and after

Workaround

No response

Works on UWP/WinUI

Yes

Environment

No response

NuGet package version(s)

5.4.5

Affected platforms

Skia (macOS)

IDE

Visual Studio Code

IDE version

No response

Relevant plugins

No response

Anything else we need to know?

No response

ArchieCoder avatar Sep 28 '24 13:09 ArchieCoder

@spouliot as discuss in email

ArchieCoder avatar Sep 28 '24 13:09 ArchieCoder

That's probably https://github.com/dotnet/runtime/issues/106144

Youssef1313 avatar Sep 28 '24 13:09 Youssef1313

That's probably https://github.com/dotnet/runtime/issues/106144

@Youssef1313 it might be related but that's using the mono runtime (in particular the interpreter), while we're using CoreCLR for the net80-desktop on macOS. Still (parts of) the slowdown might be misidentified.

The first step will be to try to reproduce this issue without any Uno bits (code or our VS extension).

spouliot avatar Sep 28 '24 13:09 spouliot

I can duplicate the issue with the attached test case.

Not a fix but using the following code does not have the same issue

           await foreach (var line in File.ReadLinesAsync(localPath))

I'll be doing a Uno-less test case asap...

spouliot avatar Sep 28 '24 15:09 spouliot

Temporary, I will use this:

#if HAS_UNO_SKIA_MACOS var lines = File.ReadAllLines(localPath); #else var lines = await File.ReadAllLinesAsync(localPath); #endif

ArchieCoder avatar Sep 29 '24 14:09 ArchieCoder

I'm not very surprised but this does not happen in a very (simplest) console app.

The code awaits in the main thread, so it's a bigger issue for a GUI app (than a console app), since a lot of things needs to happen on the main thread (even more at app startup). The debug console shows that this unknown, debug thing delays the loading of assemblies (like HarfBuzzSharp.dll).

To answer "why only in debug?" I'll need to dig further to see where that time is spent (using Instruments) but it's likely not in managed code (that would have been too easy) and possibly not fixable (at least inside Uno).

Note: unrelated to the slowdown itself but, if possible, you should avoid ReadAllLines[Async] unless you know/control how big the file will be. Otherwise you risk an OutOfMemoryException since the whole file needs to fit in memory.

Instead try reading the file line-by-line, like I suggested earlier. It should be easy since it seems you're processing the data that way. The memory usage will remain mostly constant whatever the size of the file being read.

For the main thread of an UI app several (one by line) small interruptions are way better than a single long one. The app will perform better, even when not debugging 😄

spouliot avatar Oct 04 '24 02:10 spouliot

Thanks for the convincing argument about the memory, yeah I will switch to each line.

FYI, in my official app the ReadAllLines is done in a background thread. Despite being in a background thread, the app is freezing. I don't think it should be doing this, but no need to investigate this since the proposal fixes the issue.

ArchieCoder avatar Oct 04 '24 04:10 ArchieCoder

FYI, in my official app the ReadAllLines is done in a background thread. Despite being in a background thread, the app is freezing

Hmm... that part is more surprising 🤔

but no need to investigate this since the proposal fixes the issue.

Keeping the issue opened. I'm curious to find out why 😄 but it likely won't be a top priority.

spouliot avatar Oct 04 '24 13:10 spouliot