Live data from Hacker News

Performance Tuning for .NET Core

reubenbond.github.io

61–70 of 78 posts

Re: Performance Tuning for .NET Core

#61

Earlier quoted context omitted.

What's wrong with any "use at all" of dynamic? It's just another type like object that has runtime reflection built-in and works well for interop, and without much performance problems.

>without much performance problems. Just depends on the kind of thing you are working on. For many people you could use dynamic all over, no problem. For many people that would be a disaster. (super high throughput server, things that need super low latency, games, rendering, libraries that could be used in any of those domains)

Exactly: I am usually writing backends for financial systems which need high throughput and low latency; dynamic is just a massive performance hit. And almost never needed; people usually use it because lazy in my experience.

It is just ‘faster’ for people to dump JSON into dynamic and write against that than it is to properly create structured classes. In the end ofcourse the unittests validate the JSON, the code is slow and harder to use and refactor; you would have saved time and stress actually just writing classes with proper typing.

Re: Performance Tuning for .NET Core

#62

Earlier quoted context omitted.

But you can't pass that into places that accept Foo because MyFoo isn't of the type Foo so that's a non-starter is most cases. Secondly this code generation solution is just re-implementing inheritance again poorly and with the above mentioned limitation. I fail to see how code generating a proxy is any way better than (or significantly different from) inheritance.

Hopefully the code was written to depend on interfaces and not hard coded types.

So if you implement an interface and then use code generation to create proxy from a "parent class", congratulations you just reinvented inheritance. What's the difference?

Re: Performance Tuning for .NET Core

#63
post #17
post #7

> Mark classes as sealed by default Please, no! This shouldn't be the default - it's a constant bugbear of mine where I want to extend a class from a library, and I can't because it's been sealed for no good reason.

It is a general design principle for .net libraries that you should seal a class unless you deliberately and carefully design it to be extensible. If a class is unsealed you are basically not able to change it ever again, since someone might have subclassed it and depend on all kinds of internal behavior. So it should only be done very deliberately.

This isn't just a design principle for .NET libraries, it's a SOLID design principle. All classes should be inextensible unless they are explicitly designed to be extended.

Re: Performance Tuning for .NET Core

#64

> JIT won't inline functions that throw Seriously? Never had to worry about that in Java land. What would be the reason for this?

Stack trace accuracy, maybe?

Shouldn't matter, since you're throwing at that particular location of the executing function, so the runtime still has to have a way of knowing that the code was part of an inline function along with its name.

Re: Performance Tuning for .NET Core

#65
post #46
post #9

Earlier quoted context omitted.

How do you know it's not been done for a good reason? Designing classes for extensibility is not easy. Furthermore, you can make classes extensible later on, but you can't do the reverse without breaking the API.

There are different kinds of extensibility. Designing for extensibility is not easy in the context of virtual methods. Every virtual method can be overridden, which means that you effectively need to define contracts for all your methods that can be overridden, and only call them in ways that respect those contracts. In a language where everything is virtual by default, like Java, this means all non-private methods.…

Unfortunately, the "new" keyword can override functionality.

Re: Performance Tuning for .NET Core

#66

One of the tips is to avoid Linq, which many .NET developers are hesitant to do. I made a library that lets you use Linq style convenience functions without a performance hit in many cases: https://github.com/jackmott/LinqFaster

So your library speeds up Array /T[] and List Linq operations? That's quite interesting, though usually in my experiences in Linq performance optimization the problem is usually prematurely using the wrong data type for your Linq operation. Given the immediate next bullet point in the article is about foreach operations over List , that would be my top expectation why they were seeing so much allocation in Linq. ToLi…

You just need to be careful not to allow any subsequent modifications of the original collection when doing that (assuming you're using the returned LINQ result), or you'll introduce runtime errors. Typically, my use of ToList or ToArray means I'm guarding against future runtime errors due to collection modification at the expense of memory allocation.

It sounds like you know this already, but I like to think I just saved someone from introducing a runtime error after following your advice without understanding the consequences.

Re: Performance Tuning for .NET Core

#67
post #65
post #46

Earlier quoted context omitted.

There are different kinds of extensibility. Designing for extensibility is not easy in the context of virtual methods. Every virtual method can be overridden, which means that you effectively need to define contracts for all your methods that can be overridden, and only call them in ways that respect those contracts. In a language where everything is virtual by default, like Java, this means all non-private methods.…

Unfortunately, the "new" keyword can override functionality.

It cannot, really. It can only shadow the old declaration (and isn't even necessary). This means if you have Derived : Base with such a shadowed member, then code from the library that uses a Base cannot call your shadowing member. You can't really change behaviour that way, nor break anything, except for yourself.

Re: Performance Tuning for .NET Core

#68
post #8

Earlier quoted context omitted.

I had the same thought when I saw that. There seems to be a trend to seal and lock down classes preventing any kind of extension. It sort of misses one of the main benefits of OOP and I know what I'm doing.

Instead of my rehashing the old arguments about inheritance.... http://developer-interview.com/p/oop-ood/what-are-advantages...

That's a terrible article.

> There is principle, which sounds like "favor object composition over class inheritance".

This is begging the question, isn't it? Why favor object composition over inheritance? The qualification here that's missing is "for code re-use". If your goal is simply to re-use code then you should favor composition. But if you're actually modeling an is-a relationship or trying to modify the behavior of a base class then that's not just for code re-use.

This subtly seems to have been lost. It's much easier to religiously ban all inheritance than to simply use it appropriately.

> In most cases "HAS-A" relationship is more semantically correct than "IS-A" relationship between classes.

In most, but not all cases. You will find that in most cases of inheritance in frameworks, for example, follow the is-a relationship perfectly. And you'll find most of time composition is used for has-a relationships. It's an error to mix this up but that's not the fault of inheritance.

For example, in my own software I inherit from the database context class to provide a host of features beyond what the framework provides. My context is a database context.

> Composition is more flexible than inheritance.

If you need that flexibility, great. But I don't see why having more flexibility is automatically good for the correctness of the program. If X is always implemented by Y, that's much easier to reason about.

> Inheritance breaks encapsulation.

I don't see how that's true. Your base class exposes what it wants to potential child classes so encapsulation is preserved. There are some languages that provide no limits (no protected/private/virtual/etc) but then those don't provide any encapsulation in any other situation either.

> A design based on object composition usually will have less classes.

Says who? What's the research behind this? I assume most projects have a mix of inheritance and composition as needed.

> It is possible to implement "multiple inheritance" in languages which do not support it by composing multiple objects into one.

That's not multiple inheritance -- it's just composing multiple objects using some kind of proxy. There is a difference.

> There is no conflict between methods/properties names, which might occur with inheritance.

Ok, that's a fair point.

Re: Performance Tuning for .NET Core

#70
post #17

Earlier quoted context omitted.

It is a general design principle for .net libraries that you should seal a class unless you deliberately and carefully design it to be extensible. If a class is unsealed you are basically not able to change it ever again, since someone might have subclassed it and depend on all kinds of internal behavior. So it should only be done very deliberately.

This isn't just a design principle for .NET libraries, it's a SOLID design principle. All classes should be inextensible unless they are explicitly designed to be extended.

The open/closed principle doesn’t say that. It says classes should be “open for extension” (usually meaning you are able to inherit from them and add functionality) and “closed for modification”, meaning you aren’t able to change internal implementations.

It does not say “everything should be closed by default unless explicitly marked otherwise”...

Post reply on HN