July 24, 2020
On Friday, 24 July 2020 at 03:29:14 UTC, Andrei Alexandrescu wrote:
> As far as I know there's little use of allocators, which is unlike C++ where there's a lot of excitement around them in spite of a much scarcer API. I recall there's a little use of allocators (copied to code.dlang.org and improved) in Mir. Not much else I've heard of.

There’s emsi-containers library [1]. Also, allocators are used in vibe.d in the form of dub package [2].

[1] https://github.com/dlang-community/containers
[2] https://github.com/vibe-d/vibe.d/pull/1983
July 24, 2020
On Friday, 24 July 2020 at 08:24:17 UTC, Ogi wrote:
> On Friday, 24 July 2020 at 03:29:14 UTC, Andrei Alexandrescu wrote:
>> As far as I know there's little use of allocators, which is unlike C++ where there's a lot of excitement around them in spite of a much scarcer API. I recall there's a little use of allocators (copied to code.dlang.org and improved) in Mir. Not much else I've heard of.
>
> There’s emsi-containers library [1]. Also, allocators are used in vibe.d in the form of dub package [2].
>
> [1] https://github.com/dlang-community/containers
> [2] https://github.com/vibe-d/vibe.d/pull/1983

Also libdparse and DScanner is using stdx-allocator. Dub-registry is showing only dependencies but unfortunately not "where used".

Kind regards
Andre
July 24, 2020
On Friday, 24 July 2020 at 03:23:07 UTC, Andrei Alexandrescu wrote:
> On 7/23/20 2:51 PM, Stefan Koch wrote:
>> On Thursday, 23 July 2020 at 00:47:21 UTC, Andrei Alexandrescu wrote:
>>> Was thinking about this, see https://issues.dlang.org/show_bug.cgi?id=21065.
>>>
>>> One problem I noticed with the current instrumentation of allocations is that it is extremely slow. https://github.com/dlang/dmd/pull/11381 takes care of that trivially and quickly because it takes advantage of defining one static variable per instantiation.
>> 
>> As Mathias has already point out in your issue.
>> You are instantiating more templates.
>> 
>> In the _worst_ case this can almost double the number of template instances.
>> I.E. when the new is inside a template itself.
>
> Not a problem. We must go with templates all the way, it's been that way since the STL was created and there's no going back. All transformations of nonsense C-style crap into templates in object.d have been as many success stories. If anything there's too few templates in there.

You say that, but we have seen problems, for example with the mangle-length of huge stringswitch instances.

Shortly after the introduction array comparison was bugged because, it could not compare char[] and const char[]. They were different types and would compare to false, therefore.

Where are the many success stories?

I haven't read any article about how the templates in druntime have helped anyone in great capacity, (to be honest I have not looked either).




> When "new C" is issued everything is right there for the grabs - everything! The instance size, the alignment, the constructor to call. Yet what do we do? We gladly throw all that on the floor to call a crummy C function that uses indirect access to get access to those. No wonder -trace=gc is so slow. This entire inefficient pomp and circumstance around creating an object is an embarrassment.

gc tracing is slow because it's not a priority to make it fast.

Every compiler which does inline-ing  properly, can get around the indirect calls.


>
> To say nothing about built-in hash tables. It's 2020 and we still use an indirect call for each comparison, right? We should make a vow to fix that until the next Pandemic.
>

The builtin-hash tables, are not cool, true.
But that's not because of cmps.

>> What do you envision the prototype to be like, and why couldn't that be just a function call to the runtime if a hook exists?
>
> In the simplest form:
>
> template __new_instance(C)
> if (is(C == class))
> {
>     static foreach (all overloads of __ctor in C)
>     {
>         C __new_instance(__appropriate__parameter__set)
>         {
>             ...
>         }
>     }
> }
>
> This would be a terrific opportunity to fix the perfect forwarding problem.
>

You are aware that this will create a lot of work for semantic, yes?

Whereas just emitting a call, would be O(1), fast and most of all,
predictable. Making this a template invites the error messages or templates as well.
What if the constraint fails, you get "Could not find a matching overload for '__new_instance'".
Whereas a solution which uses a function call, could give a more informative error message.

> Further improvements: use introspection to detect if the class defines its own __new_instance, and if it does, defer to it. That way the deprecated feature per-class new makes a comeback the right way.

I wonder why the feature was deprecated in the first place.

Actually it's not very costly to simply allow two ways of customizing 'opNew'.
If that were the case one could even do direct comparisons of the template vs.
the function approach.

D has always prided itself on giving the decision to the user, I don't see any compelling reason not to do it here.

Regards,
Stefan

July 24, 2020
On Friday, 24 July 2020 at 03:23:07 UTC, Andrei Alexandrescu wrote:
> On 7/23/20 2:51 PM, Stefan Koch wrote:
>> On Thursday, 23 July 2020 at 00:47:21 UTC, Andrei Alexandrescu wrote:
>>> Was thinking about this, see https://issues.dlang.org/show_bug.cgi?id=21065.
>>>
>>> One problem I noticed with the current instrumentation of allocations is that it is extremely slow. https://github.com/dlang/dmd/pull/11381 takes care of that trivially and quickly because it takes advantage of defining one static variable per instantiation.
>> 
>> As Mathias has already point out in your issue.
>> You are instantiating more templates.
>> 
>> In the _worst_ case this can almost double the number of template instances.
>> I.E. when the new is inside a template itself.
>
> Not a problem. We must go with templates all the way, it's been that way since the STL was created and there's no going back. All transformations of nonsense C-style crap into templates in object.d have been as many success stories. If anything there's too few templates in there.

You say that, but we have seen problems, for example with the mangle-length of huge stringswitch instances.

Shortly after the introduction array comparison was bugged because, it could not compare char[] and const char[]. They were different types and would compare to false, therefore.

Where are the many success stories?

I haven't read any article about how the templates in druntime have helped anyone in great capacity, (to be honest I have not looked either).




> When "new C" is issued everything is right there for the grabs - everything! The instance size, the alignment, the constructor to call. Yet what do we do? We gladly throw all that on the floor to call a crummy C function that uses indirect access to get access to those. No wonder -trace=gc is so slow. This entire inefficient pomp and circumstance around creating an object is an embarrassment.

gc tracing is slow because it's not a priority to make it fast.

Every compiler which does inline-ing  properly, can get around the indirect calls.


>
> To say nothing about built-in hash tables. It's 2020 and we still use an indirect call for each comparison, right? We should make a vow to fix that until the next Pandemic.
>

The builtin-hash tables, are not cool, true.
But that's not because of cmps.

>> What do you envision the prototype to be like, and why couldn't that be just a function call to the runtime if a hook exists?
>
> In the simplest form:
>
> template __new_instance(C)
> if (is(C == class))
> {
>     static foreach (all overloads of __ctor in C)
>     {
>         C __new_instance(__appropriate__parameter__set)
>         {
>             ...
>         }
>     }
> }
>
> This would be a terrific opportunity to fix the perfect forwarding problem.
>

You are aware that this will create a lot of work for semantic, yes?

Whereas just emitting a call, would be O(1), fast and most of all,
predictable. Making this a template invites the error messages or templates as well.
What if the constraint fails, you get "Could not find a matching overload for '__new_instance'".
Whereas a solution which uses a function call, could give a more informative error message.

> Further improvements: use introspection to detect if the class defines its own __new_instance, and if it does, defer to it. That way the deprecated feature per-class new makes a comeback the right way.

I wonder why the feature was deprecated in the first place.

Actually it's not very costly to simply allow two ways of customizing 'opNew'.
If that were the case one could even do direct comparisons of the template vs.
the function approach.

D has always prided itself on giving the decision to the user, I don't see any compelling reason not to do it here.

Regards,
Stefan

July 24, 2020
On Friday, 24 July 2020 at 03:29:14 UTC, Andrei Alexandrescu wrote:
> On 7/23/20 9:34 AM, jmh530 wrote:
>> On Thursday, 23 July 2020 at 00:47:21 UTC, Andrei Alexandrescu wrote:
>>> Was thinking about this, see https://issues.dlang.org/show_bug.cgi?id=21065.
>>>
>>> One problem I noticed with the current instrumentation of allocations is that it is extremely slow. https://github.com/dlang/dmd/pull/11381 takes care of that trivially and quickly because it takes advantage of defining one static variable per instantiation.
>> 
>> How does this fit in with plans for std.experimental.allocator? What are the current plans for std.experimental.allocator?
>
> Allocators need a champion. Ideally a good integration with the GC would be achieved but I'm not a GC expert and don't have the time to dedicate to it.
>
> As far as I know there's little use of allocators, which is unlike C++ where there's a lot of excitement around them in spite of a much scarcer API. I recall there's a little use of allocators (copied to code.dlang.org and improved) in Mir. Not much else I've heard of.
>
> I was hoping there'd be a lot of experimentation accumulating with new allocators by now, for example to this day I have no idea whether FreeTree is any good. (It never rebalances, but I thought I'd wait until someone says the trees get lopsided... still waiting).

The main issue right now with allocators IMHO are language changes that would allow for the writing of @safe smart pointers and the like.

Currently, opting out of the GC means putting up with C++-style memory safety bugs. Thankfully ldc gives us asan, but while that helps it's definitely not a silver bullet.

I want to come up with a DIP but have been busy trying to fix template code emission issues , which also tie into build times.
July 24, 2020
On 7/23/20 11:29 PM, Andrei Alexandrescu wrote:
> On 7/23/20 9:34 AM, jmh530 wrote:
>> On Thursday, 23 July 2020 at 00:47:21 UTC, Andrei Alexandrescu wrote:
>>> Was thinking about this, see https://issues.dlang.org/show_bug.cgi?id=21065.
>>>
>>> One problem I noticed with the current instrumentation of allocations is that it is extremely slow. https://github.com/dlang/dmd/pull/11381 takes care of that trivially and quickly because it takes advantage of defining one static variable per instantiation.
>>
>> How does this fit in with plans for std.experimental.allocator? What are the current plans for std.experimental.allocator?
> 
> Allocators need a champion. Ideally a good integration with the GC would be achieved but I'm not a GC expert and don't have the time to dedicate to it.
> 
> As far as I know there's little use of allocators, which is unlike C++ where there's a lot of excitement around them in spite of a much scarcer API. I recall there's a little use of allocators (copied to code.dlang.org and improved) in Mir. Not much else I've heard of.
> 
> I was hoping there'd be a lot of experimentation accumulating with new allocators by now, for example to this day I have no idea whether FreeTree is any good. (It never rebalances, but I thought I'd wait until someone says the trees get lopsided... still waiting).

iopipe uses allocators, though I had to write my own default GC allocator, because I needed an allocator that doesn't provide blocks with SCAN set.

At least in one place I used it to avoid using the heap (for a basic output pipe): https://github.com/schveiguy/iopipe/blob/0974b19e389e0c35779fa2d5b4690f775264239d/source/iopipe/bufpipe.d#L618-L633

And in action here: https://github.com/schveiguy/httpiopipe/blob/a04d87de3aa3836c07d181263c399416ba005e7c/source/iopipe/http.d#L761

I think something that might help gain more traction is to provide a mechanism to ask for typed data. Some allocators need to do things when they have types. For example, the GC can run destructors on structs when allocated properly.

If allocators are not going to provide complete replacement for GC calls, then one is going to have to use conditional compilation to make it work.

-Steve
July 24, 2020
On 7/24/20 4:58 AM, Stefan Koch wrote:
> On Friday, 24 July 2020 at 03:23:07 UTC, Andrei Alexandrescu wrote:
>> Not a problem. We must go with templates all the way, it's been that way since the STL was created and there's no going back. All transformations of nonsense C-style crap into templates in object.d have been as many success stories. If anything there's too few templates in there.
> 
> You say that, but we have seen problems, for example with the mangle-length of huge stringswitch instances.

I looked at that. It's a non-issue. Yes, there's a long mangled name for a switch statement with strings. It scales up with the number of switch statements (with strings) and the number of strings. It's called once. And that's about it. It's easy to improve (e.g. by hashing) but there's no need to.

> Shortly after the introduction array comparison was bugged because, it could not compare char[] and const char[]. They were different types and would compare to false, therefore.

So there was a bug in the implementation.

I recall there was (and there may still be) a problem with things like array comparison because the compiler did it in different ad-hoc ways depending on compile- vs. run-time execution. This would be something very worth looking into.

> Where are the many success stories?

Lucia demonstrated dramatic improvements on array comparison speed: https://www.youtube.com/watch?v=P6ZST80BCIg.

> I haven't read any article about how the templates in druntime have helped anyone in great capacity, (to be honest I have not looked either).

Problem is there are not enough.

We need to template all we can of druntime. All those silly C-style functions decaying to void* and dependencies and runtime type information must go.
July 24, 2020
On Friday, 24 July 2020 at 03:29:14 UTC, Andrei Alexandrescu wrote:
> [snip]
>
> Allocators need a champion. Ideally a good integration with the GC would be achieved but I'm not a GC expert and don't have the time to dedicate to it.
>
> As far as I know there's little use of allocators, which is unlike C++ where there's a lot of excitement around them in spite of a much scarcer API. I recall there's a little use of allocators (copied to code.dlang.org and improved) in Mir. Not much else I've heard of.
>
> I was hoping there'd be a lot of experimentation accumulating with new allocators by now, for example to this day I have no idea whether FreeTree is any good. (It never rebalances, but I thought I'd wait until someone says the trees get lopsided... still waiting).

I know mir has makeSlice and makeNdSlice that use std.experimental.allocator.

I can't speak to why people don't use them in D, but it is hard to compare to C++ where it is already part of the standard library.
July 24, 2020
On Friday, 24 July 2020 at 14:06:28 UTC, Andrei Alexandrescu wrote:
>
> Problem is there are not enough.

+2

> We need to template all we can of druntime. All those silly C-style functions decaying to void* and dependencies and runtime type information must go.

<3

One very important upsides that hasn't even been mentioned is that the compiler (+ the C-style functions) are plainly lying to us as they aren't properly type-checked.
The compiler assumes that they are e.g. `@nogc @safe pure nothrow`, but this is not always true.
This alone should be motivation enough.

Further details regarding the breakout of the type system can be found in Dan's GSoC19 project:

https://github.com/dlang/projects/issues/25
July 24, 2020
On 7/24/20 10:06 AM, Andrei Alexandrescu wrote:
> We need to template all we can of druntime. All those silly C-style functions decaying to void* and dependencies and runtime type information must go.

Yes please! Template implementations make bugs in the runtime so much easier to fix, and make features easier to add. Not to mention all the inference we lose when we don't do it this way.

Consider all the features added to AAs via templates. Even though they have to be thin wrappers around the C-style functions, it allows much better control over which calls are valid.

-Steve