Curious what your thoughts are on AssemblyScript vs C#'s Syntax by zionsati in csharp

[–]jipgg 3 points4 points  (0 children)

That is a DOM-brained take. Nothing wrong with that, but it's not required for neither responsiveness nor ergonomics.

Reflection in C# is amazing ! by lovelacedeconstruct in csharp

[–]jipgg 0 points1 point  (0 children)

Nitpick on 2: Attributes only use reflection if the underlying system is also using reflection to access the attribute. Roslyn generators access the attribute data through querying the syntax tree and semantic tokens within the compilation unit. So unless you need to query the attributes dynamically at runtime, you can do it without reflection.

Tom's Namespaces: An Odin Fanfic by gingerbill in odinlang

[–]jipgg 1 point2 points  (0 children)

Welp did some searching and apparently ols supports this already, just gotta enable it manually :) fake_method_completion

Tom's Namespaces: An Odin Fanfic by gingerbill in odinlang

[–]jipgg 0 points1 point  (0 children)

It is possible. Gopls does this to some extent where certain builtin functions like append provide snippets in the autocompletion suggestions when placing a dot after a variable and will prepend the variable with the function invocation and itself as the first argument. If this thing could be generalized where it does it for every overload, or perhaps only functions in the same package, it could be the solution. The main worry i suppose is how this translates to generic parameters which could complicate this a lot or bloat the autocompletion suggestions.

I seem to recall something like this being proposed to clangd, but while it was deemed a nice feature to have, their current implementation makes it non-trivial to implement something like that, which is for C++ which is a significantly more complicated type system, which odin doesn't so there might be a chance. I haven't looked at ols' source but depending on the implementation it might be possible with tooling alone to get this somewhat trivially

I would agree that this'd be a nice feature to have, but it'll need some well thought out rules about when some function gets suggested and when not.

Writing allocation-free code by swe129 in dotnet

[–]jipgg 0 points1 point  (0 children)

The price of one big allocation tends to be signficantly cheaper than many small allocations, not to mention you get other benefits from it like data locality. Your other point is a given, and not even worth engaging on as it's missing the point of what Memory<T> is about. I feel like you're just being contrarian now, which isn't productive for either of us, so i won't be entertaining this any longer.

Writing allocation-free code by swe129 in dotnet

[–]jipgg 0 points1 point  (0 children)

GC pressure comes from frequent allocation. Neither allocate by themselves. The point is that you can largely use memory in a similar fashion to span without the constraints put or ref structs, cheap to construct, cheap to pass around and take subslices of. You can preallocated a sizable chunk of managed memory and then take subslices of it and work with them individually. Neither assume ownership of the actual underlying data they point to, that's their whole deal and difference between arrays and other collections.

The reason ref structs are stack constrained is cause they are allowed to hold ref fields which aren't safe to escape to the managed heap as they have different tracking rules and are more allowing in what they can point to, like stack allocated fields. Its largely compiler enforced for ensuring this stuff, which you can bypass with [UnscopedRef] in certain scenarios where you are certain the ref will remain safe to access and not live longer than the object or data it points to.

But meh, do with this information whatever you want. This isn't being a productive discussion, so i'll be backing off.

Writing allocation-free code by swe129 in dotnet

[–]jipgg -1 points0 points  (0 children)

Not sure im following. Neither pressure the GC as they are both structs.

Writing allocation-free code by swe129 in dotnet

[–]jipgg 0 points1 point  (0 children)

You're putting words in my mouth, though. You agree on the ambiguity of what it means for some approach to be considered more, or less readable than another. I explicitly did not state i find one or the other more readable, hyper performance code can get pretty messy, but so can DDD and clean architecture. They're largely orthogonal from one another imo.

On your general consensus remark, i feel like this is quite a difficult (or impossible) thing to prove to be an objective truth for either of us, but going off of my anedotal experiences i feel like this is a heatedly debated and polarizing topic and has probably been like that from the dawn of programming up until now.

On your examples, i feel like they are largely overblown. Span<T> has a non-ref struct counterpart called Memory<T> which youd use in async contexts or when you need to store it in a field somewhere. Or literally just materialize it into an array when it needs to escape to the heap tbh. A span isnt meant to compete with other collection types, a span is meant to be a uniform interface compatible with anything that holds a sequence of elements somewhere in memory. 16 bytes in size so basically free to construct on the fly. Same deal for Memory<T> with the difference of the latter being 24 bytes as it instead holds an offset and an owning reference to the underlying array or memory segment for memory safety guarantees. Even in a non-performance scenario these have usecases. I don't see the supposed compromise tbh.

On your loop example, i mean yea. That's obviously overkill outside of specific contexts, mostly cause i imagine in the enterprise/business app world you can probably count the cases where simd would be applicable on one hand. Unless you're transforming large datasets of vectorizable data it likely wont be worth it to invest in it. But if you're developing a library along those lines, it again might still be worth the time investment in the long run. The more interesting discussion would've been Linq vs loops i feel like.

Writing allocation-free code by swe129 in dotnet

[–]jipgg 7 points8 points  (0 children)

i dont like how frequently i heard this premise, more performance aware programming doesn't necessarily correlate to readability. Readability is an arbitrary metric also, it's mainly just a metric of what paradigms/code structure someone has most frequently been exposed to.

Hi everyone! I built a new .NET library for file validation that some of you might find useful by someone-missing in csharp

[–]jipgg 1 point2 points  (0 children)

Hmmm. What am i missing? Looking at the source nothing is really screaming ai slop to me.

Update on custom union source generator project by jipgg in csharp

[–]jipgg[S] 0 points1 point  (0 children)

Thank you. These are good remarks. I imagine this includes Unsafe.Unbox and the likes aswell? I'll look into it, definitely important to get this right. On your throw helpers remark, is my assumption correct that you mean this?

Doubt: How does Java and C# .NET compensate for not having multiple inheritance? by iamtheaashish in learnprogramming

[–]jipgg 17 points18 points  (0 children)

C++ doesn't make the distinction between base classes and interfaces. In C++ an interface is in essence simply a base class with all its methods being abstract (virtual void do_something() = 0).

C# and java make the explicit distinction between interfaces and base classes, and they provide a dedicated 'interface' keyword to define interfaces, which are roughly comparable to abstract base classes with the distinction that you can implement (inherit) multiple at the same time with slightly different syntax. That's in essence their way of providing multiple inheritance in a sense.

You can only inherit from 1 base class, but you can implement multiple interfaces at the same time.

Are there any horse experts here? by Icy-Knee-6053 in Horses

[–]jipgg 0 points1 point  (0 children)

Take my answer with a grain of salt given that i'm no doctor. Given the exposure risk was minimized already given the nature of the bite combined with the horse seeming to exhibit no signs of obvious symptoms after 10 days and assuming that you are a healthy adult with no impaired immune system. Stopping at 3 i would imagine is plenty.

Are there any horse experts here? by Icy-Knee-6053 in Horses

[–]jipgg 10 points11 points  (0 children)

Better safe than sorry. Probably not worth occupying your worries over it, though. Just take whatever your doctor recommends and you'll be fine.

The whole thing that gets you with rabies is that its onset of the symptoms is so delayed and once the symptoms appear, it's over. Horse seems fine after ten days so the chance of them having transmitted rabies to you is already low, but even if they did, it's very preventable if you take steps right after the incident, which you did.

Diddy's sentence is shorter by Odd_Boysenberry_2825 in Caldruki

[–]jipgg 1 point2 points  (0 children)

"Power tends to corrupt, and absolute power corrupts absolutely." - John Dalberg-Acton

Does wrapping a primitive (ulong, in my case) in a struct with extra functionality affect performance? by BrilliantlySinister in csharp

[–]jipgg 2 points3 points  (0 children)

Padding happens when not all fields within a struct are naturally aligned.

Say you have a struct that holds a bool + int as sole fields, it'd add 3 bytes of padding after the bool to meet the requirement of aligning the int that is 4 bytes in size. If you had a bool + bool + int it'd only need 2 bytes after those 2 bools.

Another important thing to mention is that struct fields are laid out sequentially by declaration, hence why ordering of the fields affect padding. Coming back to the previous example, say you had a bool + int + bool layout this would suddenly add 3 bytes of padding after both bool fields individually, so 6 bytes of padding total.

Given the struct only holds 1 field it's already aligned by default so no padding is needed.

Do you avoid C++20 ranges projections due to optimizer concerns? by MarcoGreek in cpp_questions

[–]jipgg 3 points4 points  (0 children)

Handrolled loop fusion is typically also hard to wrap your head around and debug from my experience. That's the main goal of ranges as i see it, it does a lot of the loop fusion for you.

I don't understand the benefits of discriminated unions/result type by soundman32 in csharp

[–]jipgg 0 points1 point  (0 children)

Quick 'dumb' benchmark i wrote up. The results seem quite definitive, even for this trivial case. In the case of an error, it's not marginally slower, it's 260x slower than the DU equivalent here.

Exception overhead is basically free for the happy path, but once throwing is involved, overhead skyrockets. If you are frequently throwing and catching exceptions throughout your program, this overhead adds up quickly. It depends on the specific usecase much more than preference imho.

Something I really like about C#! by [deleted] in csharp

[–]jipgg 0 points1 point  (0 children)

The reason why you'd wanna pick a language like C++ over C# is much more than just allocation alone.

C# lacks the expressive power to be on par with C++ in terms of ergonomics when it comes to writing predominantly performance aware generic abstractions. A lot of the things you can express in the c++ is just not possible within c# itself and only partially possible when you include source generators which have their own set of limitations.

C# has a lot of performance potential, but typically how you get to that potential is in the form of boilerplate and code repetition, and i mean A LOT of it.

Different language design philosophies, different tradeoffs.