Does .NET on Linux just use a bunch of time-wasting OS-wrappers for functions?


#1

First time/post here…

Is my co-worker wrong? He is making the following claims about .NET on Linux:

  • .NET should only be run on Windows, because running, “.NET CLR calls on Unix are just time-wasting OS-wrappers for functions”.
  • Doing anything in UNIX from C# would be the equivalent of PInvoke.
  • The C# call will call the CLR method defined as copy for Windows – not UNIX.
  • C will not invoke UNIX:copy(a,b) unless you say something like: SystemCall(“Copy a b”);
  • C++ ->systemCall(“copy a b”) ->csh(“copy a b”);
  • C#:CopyBytes(a,b) ->CLR(CopyBytes)->.Net:CopyBytes->Xamarin:CopyBytes->Unix:_sysCall(“copy a b”)

It seems like my co-worker is wrong to me, but that’s because I’d like to think that .NET on Linux is viable, performant, etc… Plus, it would just be fun to point out the flaws in his attempt to bash Microsoft technologies. :smile:

Thanks!
-Ed


#2

.NET CLR calls on Unix are just […] OS-wrappers for functions

Many of them are. But the same applies to .Net on Windows and also any other programming language on any other operating system. FileStream.Read() in C# will make a syscall (on Unix or Windows), but so will fread() in C.

Doing anything in UNIX from C# would be the equivalent of PInvoke.

Possibly, but it depends a lot on what you’re doing. But again, the same can be said about any other language.

Also, it’s not equivalent to PInvoke, it is PInvoke.

The C# call will call the CLR method defined as copy for Windows – not UNIX.

The .Net library was originally designed to run on Windows and it shows in some places. But a lot of the concepts are pretty similar across OSes and I’m not sure if the differences will actually affect performance.

C will not invoke UNIX:copy(a,b) unless you say something like: SystemCall(“Copy a b”);

I’m not sure what is copy supposed to be (copying memory? copying data between files? copying files?). The syntax you’re showing looks similar to the C system() function, which is used to invoke commands, not execute system calls.

If you’re worried that calling File.Copy("a", "b") on .Net Core on Unix will invoke something like /bin/cp 'a' 'b', then that’s wrong. If you’re interested, the implementation is written in C++ and uses the most appropriate system call available on a given OS.

C#:CopyBytes(a,b) ->CLR(CopyBytes)->.Net:CopyBytes->Xamarin:CopyBytes->Unix:_sysCall(“copy a b”)

I really do not understand what is this supposed to mean. What is supposed to be the difference between CLR and .Net? And .Net Core on Unix has nothing to do with Xamarin or Mono.


#3

Thanks for the response :slight_smile: To answer your question, I believe my co-worker was trying to illustrate the number of layers required to process the request that that each layer would require additional processing and reduce performance overall. However, from what you’re saying, it sounds like there is not going to be a major performance difference and that .NET Core really is as exciting as it seems. :slight_smile:


#4

I believe my co-worker was trying to illustrate the number of layers required to process the request that that each layer would require additional processing and reduce performance overall.

Although it’s true that adding layers of abstraction can affect performance, such an impact is often negligible, at least when scoped to a smaller volume of work being performed (e.g., a web server with 10 req/second opposed to 10k req/second). There are some areas where additional allocations are made as a result of adding layers of abstraction, and those can affect performance on long-running apps or services. This is something we’re focusing on significantly with .NET Core. There have already been improvements on that front, such as a recent change to reduce allocations in HTTP header parsing.

If you’re interested in some of the newer stuff we’re trying out (much of which has performance as a motivator), check out the corefxlab repo.

it sounds like there is not going to be a major performance difference and that .NET Core really is as exciting as it seems.

It is exciting! :smile:

A good rule of thumb when talking about performance is to measure before you do anything. You may use a library that has tons of function calls it makes before it gets to the “bare metal”, but if you measure and find that it only adds an additional 10ms in wall clock time, those tons of function calls end up not adding up to much. You could also be writing code where every millisecond counts, and an additional 10ms of overhead is not worth the productivity gain of using that library. It could also be the case that those 10ms of overhead are fine in the short-term, but after 1 month of uptime the GC is pausing threads for seconds at a time because it has so much garbage to deal with. Like everything in life, it depends! But if you can measure, then you can start to have informed discussions about tradeoffs and how to best approach solving performance problems.

That’s really just the tip of the iceberg though. Understanding how to measure for different kinds of performance is a whole field of its own.

Hopefully this is helpful!


.NET Foundation Website | Blog | Projects | Code of Conduct