Copy-On-Write (COW) Managed Containers?

Max Haughton maxhaton at gmail.com
Tue Oct 20 22:39:43 UTC 2020


On Tuesday, 20 October 2020 at 15:52:53 UTC, Ola Fosheim Grøstad 
wrote:
> On Tuesday, 20 October 2020 at 15:28:36 UTC, IGotD- wrote:
>> I can see several cases where you want to do operations on 
>> slices, regardless if it as string or other type of elements.
>
> Yes, C++ has std::span for that. Not really sure why they also 
> wanted string_view.
>
>> anything. Previously which must be several years from now 
>> std::string used COW and the reason was it didn't scale with 
>> multiprocessor environments they claimed but I've not seen the 
>> actual reasoning behind it.
>
> I don't know. You can use COW when designing a high level 
> language for multiprocessor execution (HPC), but that is 
> something different than what we are speaking of here? And it 
> only makes sense if the compiler is able to reason about 
> concurrency.
>
>> The reason we have string_view is because around C++11 
>> std::string added the zero termination by default which wasn't 
>> required before. Now string_view is required because of this 
>> and you can really discuss if that was a sane choice.
>
> I doubt people use std::string for much more than paths and 
> names... It is a very lacklustre design, but then again, no 
> string-representation can fit all use scenarios (in low level 
> programming that is).
>
>> Also, reference counting might very well be suitable for low 
>> level programming.
>
> Yes, but not as a homogenous reference strategy.
>
>> Isn't both the array in std.container.Array and the regular 
>> built-in array COW in D?
>
> COW would require all mutable operations to test a flag in the 
> object before mutation. That is a performance killer.
>
> Maybe you are talking about optimizations? But that would not 
> be COW...

I think Facebook's string library still has flag/s for small 
string, dynamic, and COW.

The container will have flags anyway, the performance hit could 
be mitigated (I am writing a library to help measure this). For 
example, with some trickery you can turn a branch into a 
conditional move or bitops - the amortized performance benefit 
may make it worth doing too, so keep that in mind (i.e. a smaller 
container with slower flag checking may be faster than the 
opposite due to cache performance)

D has an advantange here, because the metaprogramming makes 
choosing (say) internal buffer sizes easier, and we can choose 
not to enable COW for shared types if needed.

Phobos could really use some @nogc containers using 
std.exp.allocator.


More information about the Digitalmars-d mailing list