This is an archive of the discontinued LLVM Phabricator instance.

[libc++][format] Improves parsing speed.
ClosedPublic

Authored by Mordante on Jul 9 2022, 11:58 AM.

Details

Reviewers
ldionne
vitaut
Group Reviewers
Restricted Project
Commits
rG65897292065e: [libc++][format] Improves parsing speed.
Summary

A format string like "{}" is quite common. In this case avoid parsing
the format-spec when it's not present. Before the parsing was always
called, therefore some refactoring is done to make sure the formatters
work properly when their parse member isn't called.

From the wording it's not entirely clear whether this optimization is
allowed

[tab:formatter]

and the range [pc.begin(), pc.end()) from the last call to f.parse(pc).

Implies there's always a call to f.parse even when the format-spec
isn't present. Therefore this optimization isn't done for handle
classes; it's unclear whether that would break user defined formatters.

The improvements give a small reduciton is code size:
719408 12472 488 732368 b2cd0 before
718824 12472 488 731784 b2a88 after

The performance benefits when not using a format-spec are:

Comparing ./formatter_int.libcxx.out-baseline to ./formatter_int.libcxx.out
Benchmark                                                               Time             CPU      Time Old      Time New       CPU Old       CPU New
----------------------------------------------------------------------------------------------------------------------------------------------------
BM_Basic<uint32_t>                                                   -0.0688         -0.0687            67            62            67            62
BM_Basic<int32_t>                                                    -0.1105         -0.1107            73            65            73            65
BM_Basic<uint64_t>                                                   -0.1053         -0.1049            95            85            95            85
BM_Basic<int64_t>                                                    -0.0889         -0.0888            93            85            93            85
BM_BasicLow<__uint128_t>                                             -0.0655         -0.0655            96            90            96            90
BM_BasicLow<__int128_t>                                              -0.0693         -0.0694            97            90            97            90
BM_Basic<__uint128_t>                                                -0.0359         -0.0359           256           247           256           247
BM_Basic<__int128_t>                                                 -0.0414         -0.0414           239           229           239           229

For the cases where a format-spec is used the results remain similar,
some are faster some are slower, differing per run.

Diff Detail

Event Timeline

Mordante created this revision.Jul 9 2022, 11:58 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 9 2022, 11:58 AM
Mordante requested review of this revision.Jul 9 2022, 11:58 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 9 2022, 11:58 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript

Nice improvement! It would be good to clarify in the standard that omitting parse is allowed for user-defined types. Could you open an LWG issue?

ldionne accepted this revision.Jul 12 2022, 9:57 AM

LGTM, let's wait for WG21 before skipping parse for user-defined formatters.

This revision is now accepted and ready to land.Jul 12 2022, 9:57 AM
Mordante updated this revision to Diff 444014.Jul 12 2022, 10:54 AM

Rebased to validate CI.

Nice improvement! It would be good to clarify in the standard that omitting parse is allowed for user-defined types. Could you open an LWG issue?

I'll look into that, thanks for the review!

This revision was automatically updated to reflect the committed changes.