https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90634

--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to baltic from comment #3)
> (In reply to Jonathan Wakely from comment #2)
>  
> > I'm not sure where the repeated 72 allocations come from, and can't check
> > the code right now, but the new code doesn't do it anyway.
> 
> It comes from std::string creation, which then is passed to path constructor.

No it doesn't, that's the 21 bytes.

With GCC 9.x the 72 bytes is sizeof(path), which comes from allocating a path.
It comes from each component of the path creating a vector<path> during
parsing, and then if there's only one component it empties the vector again.
Those transient allocations could be avoided, so I'll change that for GCC
8.4.0, but there's nothing to do for GCC 9.x as it's already avoiding
unnecessary vector<path> operations.

> > I think this can be considered fixed.
> 
> hardly. the gcc 9.1 is even worse in that regard, as it allocates 2kB of
> memory for the same case
> see the line:
> 
> about to quit. total allocated 2131 bytes
> 
> in here:
> https://wandbox.org/permlink/u9dEfPh1Zc5pmJ34

You should try using a real compiler and not only rely on wandbox. Maybe
there's something wrong with the wandbox compiler, but that result only happens
when using Boost (so you should take it up with Boost instead).

The correct results with 9.1.0 are:

allocating 21 bytes
allocating 248 bytes
about to quit. total allocated 269 bytes
freed 248 bytes
freed 21 bytes

(In reply to baltic from comment #4)
> besides the 269 bytes you have mentioned, is still x10 overhead for a 20
> chars string. and massively adds up, if you store a lot objects.

The overhead is linear in the number of components in the path, not the string
length. If you have a path with a single filename and no directories then the
overhead is nothing like 10x.

> for example, when i go around home folder on my machine and save all the
> found paths to vector, it takes 2.7GB, while should take ~150MB!! quite an
> overhead on a simple task, for a language which strives for efficiency.

So don't store them as filesystem::path objects then, store them as strings and
create a path as needed.

> check out clang, for example:
> https://wandbox.org/permlink/u9dEfPh1Zc5pmJ34
> it's smart enough to allocate such short strings inplace:
> about to quit. total allocated 0 bytes

GCC will also create short strings in place, but with a different limit for
what is considered "short".

GCC's implementation creates the path components eagerly, so that
path::iterator meets the requirements of a forward iterator, whereas the libc++
implementation creates them lazily during iteration, and so is not a valid
forward iterator. This fails with libc++:

https://wandbox.org/permlink/eas3ZqA2CojecrQJ

The implementations have different trade-offs. That is not a bug.

Reply via email to