News for hackers. Stuff that matters.
Re:JSON for Modern C++ version 3.10.0 by esprehn on Wednesday August 18, 2021 @11:49PM (#28230141)
This doesn't appear to be all that "modern": it doesn't support string_view for lookup without extra allocations, and it doesn't support unordered_map (or even use it as the default) for objects.

It seems they're targeting C++11?

Re:JSON for Modern C++ version 3.10.0 by nlohmann on Thursday August 19, 2021 @08:01AM (#28232745)
The development started in 2013 when C++11 was still modern. Since then, the term "modern C++" is, to my understanding, a synonym for "C++11 and later". Of course, some code may look dated compared to newer C++ constructs, but the main goal is to integrate JSON into any C++ code bases without making it look odd.

The string_view lookup is nearly done, but I did not want to wait for it, because it would have delayed the release even more.

I'm also working on supporting unordered_map - using it as container for objects would be easy if we would just break the existing API - the hard part is to support it with the current (probably bad designed) template API.

Re:JSON for Modern C++ version 3.10.0 by MauranKilom on Thursday August 19, 2021 @04:11AM (#28231521)
> and it doesn't support unordered_map (or even use it as the default) for objects.

std::unordered_map has massive overhead in space and time. Maybe I misunderstand your idea, but outside of extremely niche use cases, std::unordered_map is basically never the right tool (unless you don't care in the slightest about performance or memory overhead).

Re:JSON for Modern C++ version 3.10.0 by agent327 on Thursday August 19, 2021 @04:36AM (#28231641)
Source? A hash map should in principle be faster than a tree, with far fewer comparisons, and against a computed hash value instead of the whole object, in principle.
Re:JSON for Modern C++ version 3.10.0 by einpoklum on Thursday August 19, 2021 @06:57AM (#28232348)
Well, std::unordered_map is faster than than std::map, but it is still slow, since it uses lists for its buckets, with lots of dynamic allocation. See also:

https://stackoverflow.com/a/42588384/1593077

and the link there. Not sure that's what GP meant though.

Re:JSON for Modern C++ version 3.10.0 by agent327 on Thursday August 19, 2021 @09:15AM (#28233423)
I don't believe it has to, some kind of bucket-optimisation (multiple elements per allocation, instead of one element per allocation) should also meet all constraints the standard sets for this type.

And I don't like it when people use ridiculous hyperbole to describe what is in reality barely perceptible overhead, so it would be good if the person I originally responded to came out and defended his POV. Hopefully using actual numbers instead of agitated handwaving and screaming...

Re:JSON for Modern C++ version 3.10.0 by MauranKilom on Thursday August 19, 2021 @12:06PM (#28235582)
> some kind of bucket-optimisation (multiple elements per allocation, instead of one element per allocation) should also meet all constraints the standard sets for this type

Pretty sure that makes it impossible to implement merge without pointer/iterator invalidation, which is a constraint imposed by the standard (https://en.cppreference.com/w/cpp/container/unordered_map/me...).

> it would be good if the person I originally responded to came out and defended his POV

See https://probablydance.com/2017/02/26/i-wrote-the-fastest-has... if you want numbers, or for example this talk by the same author https://www.youtube.com/watch?v=M2fKMP47slQ.

Re:JSON for Modern C++ version 3.10.0 by beached_whale on Thursday August 19, 2021 @11:49AM (#28235338)
Abseil has a btree based hash map and it performs much better. I think it maintains the same constrains(iterator invalidation/exception safety...) as std::unordered_map.

The issue is that the implementors won't change their implementation of unordered_map as it's an ABI break, to say it simply. It could be better. But also, there are other tools like flat maps/open addressing that are not done in the std library.

Re:JSON for Modern C++ version 3.10.0 by wmkn on Thursday August 19, 2021 @08:41AM (#28233087)
What? I would argue that unordered_map is nearly always a reasonable choice when in need of an unordered associative container. There is nothing particular wrong with it.

Not sure what your rationale is for saying it’s only useful for extremely niche use cases. I would be curious to know why you think so.

Re:JSON for Modern C++ version 3.10.0 by MauranKilom on Thursday August 19, 2021 @12:17PM (#28235723)
It has the right asymptotic guarantees for a hash map, but beyond that it doesn't have much going for it. The degree to which it emphasizes pointer/iterator stability and arbitrary load factors is not a good tradeoff in almost any practical case (unless you do not care about performance).

See https://www.youtube.com/watch?v=M2fKMP47slQ for a more comprehensive discussion, or the sibling threads here.

Re:JSON for Modern C++ version 3.10.0 by spacechild1 on Thursday August 19, 2021 @06:29AM (#28232210)
> but outside of extremely niche use cases, std::unordered_map is basically never the right tool

std::map is only useful if you need the data to be ordered, otherwise std::unordered_map is the right default choice.

> std::unordered_map has massive overhead in space and time.

Yes, std::unordered_map uses a bit more memory, but please show me some benchmarks where it is slower than std::map - especially with string keys!

BTW, for very small numbers of items the most efficient solution is often a plain std::vector + linear search.

Re:JSON for Modern C++ version 3.10.0 by adzm on Thursday August 19, 2021 @08:08AM (#28232775)
> BTW, for very small numbers of items the most efficient solution is often a plain std::vector + linear search.

This is why flat_map is a great solution. It's basically an ordered vector with a map-like interface, but without the memory allocation (and cache locality issues) for each node. Until you start getting into thousands of elements it is probably the best choice of container.

Re:JSON for Modern C++ version 3.10.0 by codr7 on Thursday August 19, 2021 @07:40AM (#28232624)
It's a gradient, from the vector you mentioned all the way up to hash maps.

And ordered maps fall somewhere in the middle.

They might make sense if you're creating massive amounts of medium sized maps.

Or if you need range searches etc.

It's all compromises, there are no hard rules.

Re:JSON for Modern C++ version 3.10.0 by MauranKilom on Thursday August 19, 2021 @12:14PM (#28235679)
I didn't meant to imply it will perform worse than std::map. My point is that std::unordered_map has very particular design tradeoffs (primarily the requirement for arbitrary load factors and the bucket interface) that fundamentally impose large space and time overhead: Every node has to be stored as separately allocated linked list entry.

That's sometimes ok, particularly if you don't care about performance (beyond asymptotic behavior). But if you do, you'd probably be well-advised to try out hash map implementations that actually don't leave performance on the table by design.

Re:JSON for Modern C++ version 3.10.0 by spacechild1 on Thursday August 19, 2021 @02:45PM (#28237663)
> I didn't meant to imply it will perform worse than std::map

You literally suggested to (almost) always prefer std::map...

> Every node has to be stored as separately allocated linked list entry.

But it's basically the same for std::map. Both containers have similar design constraints. I am aware that std::unordered_map uses more memory than std::map, but why should it be slower in the general case? After all, hashtables trade memory for speed.

> But if you do, you'd probably be well-advised to try out hash map implementations that actually don't leave performance on the table by design.

I agree. But the same is true for std::map (someone has already mentioned flat maps).

Re:JSON for Modern C++ version 3.10.0 by batty_alex on Thursday August 19, 2021 @07:44AM (#28232653)
I think you might have it backwards. std::map is the one you only want to reach for in cases where you need a sorted dictionary (it sorts after insert)

std::unordered_map is typically the go-to hash map on any given C++ day. You’re probably fine with std::map outside of large n

EDIT: being pedantic

Re:JSON for Modern C++ version 3.10.0 by beached_whale on Thursday August 19, 2021 @12:25AM (#28230310)
The C++11 is still common enough that if you want a large usage group it's the target. However, it's parsing to a DOM and doesn't use features like PMR, so the language features needed won't be more than std containers and stuff.
Re:JSON for Modern C++ version 3.10.0 by quietbritishjim on Thursday August 19, 2021 @06:58AM (#28232359)
I think it makes sense to target C++11. Just that you shouldn't then call the library "modern".
Re:JSON for Modern C++ version 3.10.0 by nlohmann on Thursday August 19, 2021 @08:03AM (#28232753)
There is also a SAX parser.

But to be honest, I have not yet played around with PMR.

Re:JSON for Modern C++ version 3.10.0 by beached_whale on Thursday August 19, 2021 @08:50AM (#28233172)
I know when I was benching JSON Link, I saw 30-50% increase in perf at the time when using better allocators and PMR can help a lot there with things like bump allocators.
Re:JSON for Modern C++ version 3.10.0 by pjmlp on Thursday August 19, 2021 @01:13AM (#28230575)
Specially among the C+ community groups.
Re:JSON for Modern C++ version 3.10.0 by beached_whale on Thursday August 19, 2021 @01:34AM (#28230676)
It is changing and I saw some survey’s showing 17 around 1/2 the shops. I know for my JSON library it wouldn’t be possible without C++ 17 so it’s a loss of eyes
Re:JSON for Modern C++ version 3.10.0 by pjmlp on Thursday August 19, 2021 @01:38AM (#28230699)
Yeah, thing is how much C++17 is actually used beyond the language version.

For example, C++/WinRT is a C++17 library, yet plenty of samples use C style strings and vectors.

Re:JSON for Modern C++ version 3.10.0 by beached_whale on Friday August 20, 2021 @10:06PM (#28253438)
I use a lot of core C++17 isms. They make some things doable and others clearer. But I think C++17 really helped a lot in generic programming in addition to the containers it introduced.
Re:JSON for Modern C++ version 3.10.0 by howolduis on Thursday August 19, 2021 @12:17AM (#28230265)
people love to complain
Re:JSON for Modern C++ version 3.10.0 by rualca on Thursday August 19, 2021 @01:51AM (#28230766)
> people love to complain

Do you find it unreasonable to point out that what's been advertised doesn't match what's being offered?

Re:JSON for Modern C++ version 3.10.0 by nlohmann on Thursday August 19, 2021 @08:04AM (#28232760)
As I tried to describe earlier: "modern C++" is not necessarily "using the latest standard", but rather "C++ since it was updated with C++11 (and later)".
Re:JSON for Modern C++ version 3.10.0 by rualca on Thursday August 19, 2021 @08:08AM (#28232778)
Aiming at C++11 is not a reasonable definition of "modern", as it was C++'s second ISO standard that was published a decade ago and which has since seen between two and three major updates (depending on the opinions on c++14)
Re:JSON for Modern C++ version 3.10.0 by nlohmann on Thursday August 19, 2021 @08:13AM (#28232814)
It's not the "aiming at C++11", but rather "Write code that does not look odd in a code base that is using constructs from C++11, C++14, C++17, etc." - The library uses C++11 to implement an API that should not feel weird when used together with other containers from the STL.
Re:JSON for Modern C++ version 3.10.0 by maleldil on Thursday August 19, 2021 @08:22AM (#28232881)
C++11 was a huge shift in how C++ is written, and term coined for "code written using the new techniques" was "Modern C++". Whether you think that term should instead mean "the latest C++ version" is a different matter altogether.
Re:JSON for Modern C++ version 3.10.0 by bobnamob on Thursday August 19, 2021 @08:21AM (#28232868)
In C++ land "modern" has become synonymous with post 11. Effectively a domain specific definition. Reasonable considering the difference between pre and post 11. Pre and post 20 will probably be treated similarly in a decade
Re:JSON for Modern C++ version 3.10.0 by q-rews on Thursday August 19, 2021 @01:18AM (#28230600)
People love correct statements. C++11 was release 10 years ago and there are 3 newer versions.
Re:JSON for Modern C++ version 3.10.0 by adzm on Thursday August 19, 2021 @08:03AM (#28232750)
You can provide alternative collections if needed by templating basic_json; std::map is just a default. Personally I like using a flat_map which is an ordered map built on top of a vector, which provides nice cache locality and is generally even faster than a hash map / unordered_map except for extremely large objects.
Re:JSON for Modern C++ version 3.10.0 by pjmlp on Thursday August 19, 2021 @01:12AM (#28230570)
For many even using RAII, which even Turbo Vision for MS-DOS made use of, is already "modern".
Re:JSON for Modern C++ version 3.10.0 by mike_hock on Thursday August 19, 2021 @04:29AM (#28231618)
It uses the ordering of std::map for its own comparison operators and hash function.