Live data from Hacker News

Allocation is cheap in .NET until it is not

tooslowexception.com

11–20 of 67 posts

Re: Allocation is cheap in .NET until it is not

#11
post #2

This article demonstrates why generational GC with a bump-allocating nursery is so important. Without a semispace copying collector (which is usually impractical without a generational GC) you can't have bump allocation at all . Not having that fast path is a huge performance loss, as this article demonstrates.

Mark-sweep-compact is another GC algorithm that supports bump allocation, and doesn't have the 2x overhead of semispace.

Re: Allocation is cheap in .NET until it is not

#13
post #6

Earlier quoted context omitted.

This pattern was also used by Java and .NET for implementing cheap String.substring calls where all substrings would use the same underlying array with just offsets changed. Unfortunately it turns out that people read entire files into a one big String and then have a reference to just a small piece of it (via substring) marking the big underlying array as reachable for the GC holding a lot of memory for no reason. T…

I know this was changed recently-ish in Java, but I hadn't heard of anybody doing the old substring trick in .NET, do you know when they cut over?

There is a lot of good things going on in .NET Core about this. Here is a good description of Span: http://adamsitnik.com/Span/#slicing-without-managed-heap-all...

Re: Allocation is cheap in .NET until it is not

#14
post #3

This brought memories of that pattern (flyweight?) where the data was stored outside the objects, possibly in an array. An object was instantiated only to hold an index to the array position and allow access. That's dirty cheap!

QPX also stored their database in non-GC space in order to prevent the GC from having to walk it.

Re: Allocation is cheap in .NET until it is not

#15
post #9

Is there work ongoing or planned to try to add/improve escape analysis, as the article suggests?

.net already has in-place allocated types (e.g. 'structs') which are dropped on the stack or inside the allocation of their owner (in the case of members fields), which explicitly covers most cases that escape analysis tries to handle implicitly. However, they still need to be heap-alloc'd when boxed (e.g. when used as a IEnumerator or something), which would definitely benefit from hotspot-style allocation-inlining (though the C# compiler already tries to do this prejit for common cases like iterators, too, for practicality's sake).

Re: Allocation is cheap in .NET until it is not

#16
post #6

Earlier quoted context omitted.

This pattern was also used by Java and .NET for implementing cheap String.substring calls where all substrings would use the same underlying array with just offsets changed. Unfortunately it turns out that people read entire files into a one big String and then have a reference to just a small piece of it (via substring) marking the big underlying array as reachable for the GC holding a lot of memory for no reason. T…

I know this was changed recently-ish in Java, but I hadn't heard of anybody doing the old substring trick in .NET, do you know when they cut over?

AFAIK this trick was never possible in .NET because Substring always 'deep copied' the relevant data into a completely new string

Re: Allocation is cheap in .NET until it is not

#17
post #2

This article demonstrates why generational GC with a bump-allocating nursery is so important. Without a semispace copying collector (which is usually impractical without a generational GC) you can't have bump allocation at all . Not having that fast path is a huge performance loss, as this article demonstrates.

I didn't understand a bit of that

Re: Allocation is cheap in .NET until it is not

#18
post #2

This article demonstrates why generational GC with a bump-allocating nursery is so important. Without a semispace copying collector (which is usually impractical without a generational GC) you can't have bump allocation at all . Not having that fast path is a huge performance loss, as this article demonstrates.

Immix [1] does bump allocation without the space overhead of the copying young generation. It's been working really well for us in Scala Native.

[1] https://dl.acm.org/citation.cfm?id=1375586

Re: Allocation is cheap in .NET until it is not

#19
post #12
post #9

Is there work ongoing or planned to try to add/improve escape analysis, as the article suggests?

In general - yes: https://github.com/dotnet/coreclr/issues/1784 . However, nothing more specific I can say...

For a VM as mature as .NET, I am surprised they don't do escape analysis. Java and Go both do escape analysis, though the coreclr issue you linked to makes the point that Java really needs escape analysis because it doesn't have value types like C# structs.

Re: Allocation is cheap in .NET until it is not

#20
post #2

This article demonstrates why generational GC with a bump-allocating nursery is so important. Without a semispace copying collector (which is usually impractical without a generational GC) you can't have bump allocation at all . Not having that fast path is a huge performance loss, as this article demonstrates.

Mark-sweep-compact is another GC algorithm that supports bump allocation, and doesn't have the 2x overhead of semispace.

[deleted]
Post reply on HN