r/programming • • 23h ago

C vs C#: racing VLC's Gaussian blur

https://martinfinkel.com/blog/gaussian-blur-c-vs-csharp/
44 Upvotes

27 comments sorted by

49

u/Khavel_dev 17h ago

The gap between C and C# for this stuff has gotten absurdly small tbh. Between Span<T>, stackalloc, and System.Runtime.Intrinsics for SIMD, you can write C# that the JIT turns into basically the same machine code. .NET 9/10 have been quietly shipping perf wins that most people haven't noticed yet.

9

u/javasuxandiloveit 12h ago

Same applies to Java but people keep making fun of it as if it were still old days.

7

u/Sopel97 6h ago

the problem with java is just that optimized code is worse than C to maintain, in C# you can actually use abstractions

-2

u/javasuxandiloveit 6h ago

That’s such untrue statement. Please give me an example! I'm used to working on it in millions scale, in telco environment, you name it, its just untrue, under no circumstances is worse than C. Found it even better to read due to verbosity than c# but thats subjective.

8

u/Sopel97 5h ago edited 55m ago

Plenty of cases in minecraft modding where structures get decomposed into primitives due to lack of availability of stack allocations. Plenty of cases where thread local instances are used as temporaries because allocations are not free. You're then left with maintaining temporal coupling all over the place whereas in C you just use a struct like a normal person.

edit. some examples with the simplest things

you end up with stuff like this at best https://github.com/GTNewHorizons/CodeChickenCore/blob/a9643dba1cfa0ab8f19c299096f79e377d672d7d/src/main/java/codechicken/lib/render/CCModelLibrary.java#L84-L92

and stuff like this at worst https://github.com/GTNewHorizons/GTNHLib/blob/d6dbd83308fd72252c6033d59b0e1915e1a5977f/src/main/java/com/gtnewhorizon/gtnhlib/util/CoordinatePacker.java#L7 -> https://github.com/GTNewHorizons/GT5-Unofficial/blob/315a38a3120f4aa24b6fee7471be9a8f55d22f5c/src/main/java/gregtech/api/net/GTPacketBlockEvent.java#L60-L64

you also end up with abominations like this when working with collections of small objects https://github.com/GTNewHorizons/GT5-Unofficial/blob/315a38a3120f4aa24b6fee7471be9a8f55d22f5c/src/main/java/gregtech/common/data/BlockPosMap.java#L22

edit 2. thread local for temporaries abomination https://github.com/GTNewHorizons/Hardcore-Ender-Expansion/blob/abfc9640f622389a81ca6e1c6b6acce928c0f44b/src/main/java/chylex/hee/system/util/BlockPosM.java#L40-L42 -> https://github.com/GTNewHorizons/Hardcore-Ender-Expansion/blob/abfc9640f622389a81ca6e1c6b6acce928c0f44b/src/main/java/chylex/hee/item/ItemCurse.java#L40

3

u/jimmy90 5h ago

i went to the latest version of a jetbrains ide recently and it's still clunky af

6

u/Kamii0909 12h ago

Every CLR new perf optimizations have been done in HotSpot since forever but it is just easier to glaze a language if you are not force to write Java ancient syntax. Newer versions do help, though.

1

u/ziplock9000 4h ago

Naa. That stopped quite a long time ago.

4

u/Saint_Nitouche 5h ago

Quietly? Stephen Toub writes a 50,000 word blogpost every year detailing all the perf improvements to .NET every year. Why 'quietly'? Is there an 'honest caveat' we have to be aware of, too?

1

u/ziplock9000 4h ago

Why is this a confusing concept for you? C# uplifts generation on generation don't get the same fanfare other languages and frameworks get.

1

u/Saint_Nitouche 4h ago

I was referring to the fact that the original comment is AI engagement bait.

25

u/yanitrix 16h ago

I love how multipurpose c# is. If you want to write something fast with memory safety not caring about performance you just do it. If you need something performance critical you can go low-level use things like stackalloc, spans, or even raw pointers and allocate memory yourself. If you want to ditch the runtime you can just use AOT. And then you can even write fucking frontend in it.

9

u/EliSka93 14h ago

Writing a frontend with C# Blazor WASM is so nice. It cuts down on about 98% of the JavaScript I'd have to write. There's barley any context switching.

9

u/Eisenfuss19 16h ago

AOT does come with a dotnet runtime embeded. It just skips saving the IL representation and compiles the IL at build time to machine code.

2

u/Saint_Nitouche 5h ago

Not to mention all the gamedev workloads where it's the most natural choice.

1

u/yanitrix 5h ago

but isn't it just unity?

3

u/Saint_Nitouche 5h ago

Monogame and Godot also let you write C#. Those three combined probably make up a decent proportion of all games on Steam. Terraria has made like over $100M and is written in Monogame (horrifying but true).

1

u/ziplock9000 4h ago

I moved back to monogame after 5-6 projects on Unity and I can tell you the project is far more stable and progressing faster. Unity is an illusion, a house of cards a lot of the time.

1

u/ziplock9000 4h ago

No, not by a long way. Even if it was Unity accounts for a huge amount of all games.

5

u/RecognitionOwn4214 15h ago

Do you think your optimized versions will make their way into VLC?

8

u/mtz94 15h ago

Optimized C versions, yes, I've already opened some merge requests.

But the better approach would be to write a gpu-based implementation for each cpu filter. We're doing it.

1

u/Dwedit 11h ago edited 11h ago

The traditional way to optimize a blur is to blur horizontally, then blur vertically. That way you avoid visiting a square region around every pixel.

Then if you want to optimize for memory use/memory bandwidth, you change the full-sized temporary buffer into a sliding window.

But things like blur filters are usually best done as a pixel shader rather than done on the CPU.

-12

u/nukethebees 15h ago

For everything else, the language you are most productive in, plus a good algorithm, will get you further.

I wouldn't make this the take-away when the author had to keep rewriting the implementation until it matched Clang.

The C# in code in the end is almost C. At that point, why not just write this in C and call it from C#?

12

u/mtz94 15h ago
  1. When the last 10% don't matter, yes it's a good take away.

  2. Because the point was to experiment how far I could take C#. Regardless, there are many valid reasons to write C# for perf sensitive code as well (team skills, interop with other dotnet libs, portability, etc.)

-8

u/nukethebees 15h ago

When the last 10% don't matter, yes it's a good take away.

It's not just the performance, it's also the development time. You essentially wrote a version in C and then used Claude to keep rewriting the C# until it matched the C. You could just have written the C version, called it in C#, and stopped there.

Because the point was to experiment how far I could take C#.

Any language that compiles to machine code can theoretically achieve the same performance. To take that argument to its logical extreme, languages with inline assembly are equally fast. We know this isn't true for the general case.

I'm sure it was fun to do but at the point where you're busting out unsafe blocks, hand-writing intrinsics, and restructuring the code to get around the compiler, the language doesn't really matter anymore. It's not really C# as people know it any longer.

10

u/mtz94 14h ago

Yes unsafe C# does not look like regular C#. That's ok.

I'm not saying all C software needs to be written in higher-level languages. I'm showing what C# can do with some optimization. That is all.

And your development time argument is no longer true with proper AI assisted programming.

3

u/yanitrix 5h ago

It's not really C# as people know it any longer.

It is. C# has many faces, unsafe code is one of them.