runtime: Slow Console.SetCursorPosition on Linux in .NET core

From @markfinal on September 7, 2018 21:37

I’ve noticed a performance oddity in some console logging code, but only on Linux. It’s working as expected in Windows and macOS. I’ve simplified it down to a small test case.

Repro steps:

  1. create new directory & cd to it
  2. dotnet new console
  3. copy the gist content into Program.cs
  4. dotnet build -c Release <csproj>
  5. dotnet <path to generated assembly .dll>

On Linux (Ubuntu 14):

mark@ubuntu:/tmp/test$ dotnet bin/Release/netcoreapp2.1/test.dll 
Hello World! 0%Hello World! 1%Hello World! 2%Hello World! 3%Hello World! 4%Hello World! 5%Hello World! 6%Hello World! 7%Hello World! 8%Hello World! 9%Hello World! 10%Hello World! 11%Hello World! 12%Hello World! 13%Hello World! 14%Hello World! 15%Hello World! 16%Hello World! 17%Hello World! 18%Hello World! 19%Hello World! 20%Hello World! 21%Hello World! 22%Hello World! 23%Hello World! 24%Hello World! 25%Hello World! 26%Hello World! 27%Hello World! 28%Hello World! 29%Hello World! 30%Hello World! 31%Hello World! 32%Hello World! 33%Hello World! 34%Hello World! 35%Hello World! 36%Hello World! 37%Hello World! 38%Hello World! 39%Hello World! 40%Hello World! 41%Hello World! 42%Hello World! 43%Hello World! 44%Hello World! 45%Hello World! 46%Hello World! 47%Hello World! 48%Hello World! 49%Hello World! 50%Hello World! 51%Hello World! 52%Hello World! 53%Hello World! 54%Hello World! 55%Hello World! 56%Hello World! 57%Hello World! 58%Hello World! 59%Hello World! 60%Hello World! 61%Hello World! 62%Hello World! 63%Hello World! 64%Hello World! 65%Hello World! 66%Hello World! 67%Hello World! 68%Hello World! 69%Hello World! 70%Hello World! 71%Hello World! 72%Hello World! 73%Hello World! 74%Hello World! 75%Hello World! 76%Hello World! 77%Hello World! 78%Hello World! 79%Hello World! 80%Hello World! 81%Hello World! 82%Hello World! 83%Hello World! 84%Hello World! 85%Hello World! 86%Hello World! 87%Hello World! 88%Hello World! 89%Hello World! 90%Hello World! 91%Hello World! 92%Hello World! 93%Hello World! 94%Hello World! 95%Hello World! 96%Hello World! 97%Hello World! 98%Hello World! 99%
Without carriage return in 2 ms
Hello World! 99%
With carriage return in 3097 ms

On macOS (10.13.6)

mark-mba:tmp mark$ dotnet bin/Release/netcoreapp2.1/tmp.dll
Hello World! 0%Hello World! 1%Hello World! 2%Hello World! 3%Hello World! 4%Hello World! 5%Hello World! 6%Hello World! 7%Hello World! 8%Hello World! 9%Hello World! 10%Hello World! 11%Hello World! 12%Hello World! 13%Hello World! 14%Hello World! 15%Hello World! 16%Hello World! 17%Hello World! 18%Hello World! 19%Hello World! 20%Hello World! 21%Hello World! 22%Hello World! 23%Hello World! 24%Hello World! 25%Hello World! 26%Hello World! 27%Hello World! 28%Hello World! 29%Hello World! 30%Hello World! 31%Hello World! 32%Hello World! 33%Hello World! 34%Hello World! 35%Hello World! 36%Hello World! 37%Hello World! 38%Hello World! 39%Hello World! 40%Hello World! 41%Hello World! 42%Hello World! 43%Hello World! 44%Hello World! 45%Hello World! 46%Hello World! 47%Hello World! 48%Hello World! 49%Hello World! 50%Hello World! 51%Hello World! 52%Hello World! 53%Hello World! 54%Hello World! 55%Hello World! 56%Hello World! 57%Hello World! 58%Hello World! 59%Hello World! 60%Hello World! 61%Hello World! 62%Hello World! 63%Hello World! 64%Hello World! 65%Hello World! 66%Hello World! 67%Hello World! 68%Hello World! 69%Hello World! 70%Hello World! 71%Hello World! 72%Hello World! 73%Hello World! 74%Hello World! 75%Hello World! 76%Hello World! 77%Hello World! 78%Hello World! 79%Hello World! 80%Hello World! 81%Hello World! 82%Hello World! 83%Hello World! 84%Hello World! 85%Hello World! 86%Hello World! 87%Hello World! 88%Hello World! 89%Hello World! 90%Hello World! 91%Hello World! 92%Hello World! 93%Hello World! 94%Hello World! 95%Hello World! 96%Hello World! 97%Hello World! 98%Hello World! 99%
Without carriage return in 3 ms
Hello World! 99%
With carriage return in 54 ms

On Windows (8.1):

C:\Users\mark\AppData\Local\Temp\test>dotnet bin\Release\netcoreapp2.1\test.dll
Hello World! 0%Hello World! 1%Hello World! 2%Hello World! 3%Hello World! 4%Hello
 World! 5%Hello World! 6%Hello World! 7%Hello World! 8%Hello World! 9%Hello Worl
d! 10%Hello World! 11%Hello World! 12%Hello World! 13%Hello World! 14%Hello Worl
d! 15%Hello World! 16%Hello World! 17%Hello World! 18%Hello World! 19%Hello Worl
d! 20%Hello World! 21%Hello World! 22%Hello World! 23%Hello World! 24%Hello Worl
d! 25%Hello World! 26%Hello World! 27%Hello World! 28%Hello World! 29%Hello Worl
d! 30%Hello World! 31%Hello World! 32%Hello World! 33%Hello World! 34%Hello Worl
d! 35%Hello World! 36%Hello World! 37%Hello World! 38%Hello World! 39%Hello Worl
d! 40%Hello World! 41%Hello World! 42%Hello World! 43%Hello World! 44%Hello Worl
d! 45%Hello World! 46%Hello World! 47%Hello World! 48%Hello World! 49%Hello Worl
d! 50%Hello World! 51%Hello World! 52%Hello World! 53%Hello World! 54%Hello Worl
d! 55%Hello World! 56%Hello World! 57%Hello World! 58%Hello World! 59%Hello Worl
d! 60%Hello World! 61%Hello World! 62%Hello World! 63%Hello World! 64%Hello Worl
d! 65%Hello World! 66%Hello World! 67%Hello World! 68%Hello World! 69%Hello Worl
d! 70%Hello World! 71%Hello World! 72%Hello World! 73%Hello World! 74%Hello Worl
d! 75%Hello World! 76%Hello World! 77%Hello World! 78%Hello World! 79%Hello Worl
d! 80%Hello World! 81%Hello World! 82%Hello World! 83%Hello World! 84%Hello Worl
d! 85%Hello World! 86%Hello World! 87%Hello World! 88%Hello World! 89%Hello Worl
d! 90%Hello World! 91%Hello World! 92%Hello World! 93%Hello World! 94%Hello Worl
d! 95%Hello World! 96%Hello World! 97%Hello World! 98%Hello World! 99%
Without carriage return in 19 ms
Hello World! 99%
With carriage return in 19 ms

Note the time with carriage return on Linux being an order of magnitude slower than both macOS and Windows.

Both Linux and macOS are running in bash shells. Windows was in a CMD prompt.

Environments: macOS: mark-mba:tmp mark$ dotnet --info .NET Core SDK (reflecting any global.json): Version: 2.1.302 Commit: 9048955601

Windows: C:\Users\mark\AppData\Local\Temp\test>dotnet --info .NET Core SDK (reflecting any global.json): Version: 2.1.401 Commit: 91b1c13032

Linux: mark@ubuntu:/tmp/test$ dotnet --info .NET Core SDK (reflecting any global.json): Version: 2.1.401 Commit: 91b1c13032

Does anyone have an idea of why Linux is so slow?

Copied from original issue: dotnet/coreclr#19871

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 1
  • Comments: 21 (14 by maintainers)

Most upvoted comments

Confirmed: my class being used in a TTY terminal is lightning fast.

I see this in bash on Ubuntu 18. I wrote a threaded output class, and need to reposition the cursor as multiple threads update their lines of output. Linux is painfully slow. macOS is a bit slower than Windows, but decent. I haven’t determined if linefeeds and cursor movement cause it, or just cursor movement.

On a related note, the fact that Windows returns cursor top positions relative to the line buffer (absolute) and others return top positions relative to the screen height, is a real pain too 😃