Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft: Reduce template bloat in std.format #8247

Closed
wants to merge 58 commits into from

Conversation

nordlow
Copy link
Contributor

@nordlow nordlow commented Sep 19, 2021

This, for instance, reduces memory usage of unittest-checking std.format.write as

dmd -o- -vcolumns -wi -debug -unittest -dip25 -dip1000 -version\=StdUnittest -I/home/per/Work/phobos/ /home/per/Work/phobos/std/format/write.d

from 386 MB to 356 MB.

  1. Motive of added const qualifers is to have, for instance,
format(fmt, int.init)
format(fmt, const(int).init)
format(fmt, immutable(int).init)
...

all result in the same template instance of format.

  1. I've factored out integer printing to make the code not be instantiated for each integral type potentially reducing generated code a lot when formatting and printing integrals. Separate PR at Reduce template bloat in IntegralTypeOf-overload of formatValueImpl #8278.

  2. The refactoring in formatValue avoids the need to instantiate the wrapper templates BooleanTypeOf, IntegralTypeOf, etc.

I'm gonna look into other types classes such as floating point types next.

Putting this out into the open to see what CIs feel about this.

Feel free to tell me how you want this split up.

@dlang-bot
Copy link
Contributor

Thanks for your pull request and interest in making D better, @nordlow! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + phobos#8247"

std/format/write.d Outdated Show resolved Hide resolved
std/format/internal/write.d Outdated Show resolved Hide resolved
@nordlow nordlow changed the title Draft: Reduce template bloat in std.format Reduce template bloat in std.format Sep 20, 2021
@RazvanN7
Copy link
Collaborator

RazvanN7 commented Sep 21, 2021

Irrespective of the memory gains, I think that having the parameter to format being const makes sense on its own as I cannot imagine any scenario where the argument might get modified.


void formatValueImplBool(Writer, Char)(auto ref Writer w, const(bool) val, scope const ref FormatSpec!Char f)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fail to understand how factoring code out into a new template declaration reduces template bloat

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I understand now. Code that is the same for each template instance should be factored out so that the generated code is smaller.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, I think that such optimizations should be benchmarked on their own. It is hard to assess the impact of this optimization when it is bundled with others. I suggest splitting this PR into different ones and assess the gains on their own. There must be a proven benefit to accept such code surgery.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

@nordlow nordlow requested a review from ibuclaw as a code owner September 22, 2021 15:33
@RazvanN7
Copy link
Collaborator

RazvanN7 commented Oct 9, 2021

@nordlow this is currently failing the testing pipeline.

@nordlow
Copy link
Contributor Author

nordlow commented Oct 9, 2021

@nordlow this is currently failing the testing pipeline.

Thanks. I'm gonna branch of minor changes from this. So I'm gonna wait with fixing this.

@nordlow nordlow changed the title Reduce template bloat in std.format Draft: Reduce template bloat in std.format Oct 9, 2021
@nordlow
Copy link
Contributor Author

nordlow commented Oct 9, 2021

This PR currently has two issue that blocks a complete reduction of code bloat in template-variadic formatting and printing functions like std.format.format. These are

auto format(T...)(const(T) args) {}

fails when any of the args is a struct with at least one field being a const class (which is related to the lack of expressing head-mutable class fields in D without resorting to the Rebindable-hack which, btw, contamintes logic in hasAliasing). There is currently no test for this case in Phobos so those need to be added aswell.

auto format(T...)(const T args) {}

fails when any of the args is an InputRange. We might be able to define two overloads of formatValue; one taking a mutable T when isInputRange!(T) and one taking a const T arg when !isInputRange!(T).

These two issues also holds for std.format.text(), write(), writeln(), and trace... functions in std.experimental.logging which are subject to the same parameter qualification as format.

Afaict, both are related to lack of

  • language support for expressing tail-const (head-mutable) pointer and class fields and
  • implicit conversion of a struct S from const to tail-const (head-mutable) when S has any const field being either pointer or class. @andralex has previously eluded to that those rules are subject to relaxation.

I'm personally not sure which alternative is the best long-term.

FYI, @adamdruppe @maxhaton.

@nordlow nordlow force-pushed the faster-formatValue branch from cd57a90 to 0eaeb78 Compare October 18, 2021 06:00
@RazvanN7
Copy link
Collaborator

RazvanN7 commented Jan 7, 2022

@nordlow I don't know of any plans to introduce tail-constness into the language, so I suggest, in the interest of progress to implement in this PR whatever works and is not dependent on tail-constness. Otherwise, this will be stalled forever.

@RazvanN7 RazvanN7 marked this pull request as draft January 25, 2022 13:17
@LightBender LightBender added the Review:Phantom Zone Has value/information for future work, but closed for now label Oct 27, 2024
@LightBender
Copy link
Contributor

PR closed as stalled. This can be resurrected for Phobos 3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Merge:Needs Rebase Merge:stalled Review:Needs Work Review:Phantom Zone Has value/information for future work, but closed for now
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants