Marwes / combine

A parser combinator library for Rust
https://docs.rs/combine/*/combine/
MIT License
1.29k stars 93 forks source link

Adivce on reducing code size in WASM target #349

Closed ruslantalpa closed 2 years ago

ruslantalpa commented 2 years ago

According to rust/wasm docs, using generic functions can lead to a lot of bloat since the compiler creates copies of those functions.

I suspect that in my case, this is the reason why 140K in a .rs file for a parser generates about 600K of WASM bytecode.

Is there a possible solution for this (work around it by writing the parser functions differently)? It seems the most common "offenders" are choice between many combinators in my case since i use them extensively.

Thank you (and thank you for the lib, it was quite straightforward to port parser from parsec)

Marwes commented 2 years ago

https://github.com/dtolnay/cargo-llvm-lines can be quite useful to track down where you end up with to many instantiations of some code but without an example of how your parser looks I can't really say anything specific.

In combine itself, it may be possible to move partial parsing behind a feature flag, allowing you to avoid including the code for it if it isn't necessary. It may be a bit complicated to implement though.

ruslantalpa commented 2 years ago

thank you for the reply, i'll try the tool you suggested,

I've used twiggy to get a sense of what's happening and the output looks like this

 Apprx. Bloat Bytes │ Apprx. Bloat % │ Bytes   │ %      │ Monomorphizations
────────────────────┼────────────────┼─────────┼────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
             617231 ┊          6.11% ┊  625832 ┊  6.20% ┊ combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl
                    ┊                ┊    8601 ┊  0.09% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::h925d4406c8fc576e
                    ┊                ┊    8478 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::hbbaea62795395eda
                    ┊                ┊    8412 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::h8d4fd74c34cabcaa
                    ┊                ┊    8291 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::h071fa112d995f497
                    ┊                ┊    8291 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::h8eff6de5dde0b06a
                    ┊                ┊    7769 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::he7da37fbe9882948
                    ┊                ┊    7648 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::h1851d8bb292757f1
                    ┊                ┊    7211 ┊  0.07% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::hd250b51943a4b37d
                    ┊                ┊    6940 ┊  0.07% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::h7a973905ebd1a99a
                    ┊                ┊    6921 ┊  0.07% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::h75e86826f4ac421b
                    ┊                ┊  547270 ┊  5.42% ┊     ... and 103 more.
             415092 ┊          4.11% ┊  425043 ┊  4.21% ┊ <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice
                    ┊                ┊    9951 ┊  0.10% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h05ed7e9bfc92ca6b
                    ┊                ┊    9951 ┊  0.10% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::hffa0f244f237174a
                    ┊                ┊    9908 ┊  0.10% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h3fae96c0b75d1382
                    ┊                ┊    9908 ┊  0.10% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h4ad48a6fc27c4fa7
                    ┊                ┊    9553 ┊  0.09% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h5667816c7385eeeb
                    ┊                ┊    9543 ┊  0.09% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::hcf3bd7133771c484
                    ┊                ┊    9527 ┊  0.09% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h28be9e37ceb1913e
                    ┊                ┊    9487 ┊  0.09% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h94023f756aac21ef
                    ┊                ┊    9284 ┊  0.09% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h0a66ba8736e614fe
                    ┊                ┊    9221 ┊  0.09% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h48fa1a798764c9c8
                    ┊                ┊  328710 ┊  3.26% ┊     ... and 46 more.
             221446 ┊          2.19% ┊  224448 ┊  2.22% ┊ <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl
                    ┊                ┊    3002 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::h9014c3edb649c9c1
                    ┊                ┊    2978 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::h56e3aa3995d240d6
                    ┊                ┊    2978 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::h63776718b99cb7e6
                    ┊                ┊    2570 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::h511c95ff6d017143
                    ┊                ┊    2570 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::h734cd160b7af22aa
                    ┊                ┊    2570 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::hcc9ca612bb8ac6b0
                    ┊                ┊    2570 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::hd59bd5773699ae9b
                    ┊                ┊    2546 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::h028e4945d7c2643a
                    ┊                ┊    2546 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::h40da6c149e57fac9
                    ┊                ┊    2546 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::h542ec3b09cf6abe4
                    ┊                ┊  197572 ┊  1.96% ┊     ... and 123 more.
             154763 ┊          1.53% ┊  163926 ┊  1.62% ┊ combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl
                    ┊                ┊    9163 ┊  0.09% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::he09458e7bbb0f3d4
                    ┊                ┊    8989 ┊  0.09% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::h6ea2e5ee3d2e4e1f
                    ┊                ┊    8200 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::h306c32afff2074e5
                    ┊                ┊    8200 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::h5fb9ee9ac2a3631f
                    ┊                ┊    8200 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::ha5b13ee17229444e
                    ┊                ┊    8200 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::hd9360bd380c37f28
                    ┊                ┊    8200 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::hfd4cb0c31063ce02
                    ┊                ┊    8199 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::h911941cb6be0f5bf
                    ┊                ┊    8158 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::h637ea8a30a2c43d5
                    ┊                ┊    8158 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::hbd8c0466a944c321
                    ┊                ┊   80259 ┊  0.79% ┊     ... and 10 more.
             151681 ┊          1.50% ┊  154249 ┊  1.53% ┊ combine::error::ParseResult<T,E>::map
                    ┊                ┊    2568 ┊  0.03% ┊     combine::error::ParseResult<T,E>::map::h095562610f15cd24
                    ┊                ┊    2568 ┊  0.03% ┊     combine::error::ParseResult<T,E>::map::h385a21a85a22633c
                    ┊                ┊    2568 ┊  0.03% ┊     combine::error::ParseResult<T,E>::map::h697ed41024bc1686
                    ┊                ┊    2568 ┊  0.03% ┊     combine::error::ParseResult<T,E>::map::h83e48d83ed803f7a
                    ┊                ┊    2568 ┊  0.03% ┊     combine::error::ParseResult<T,E>::map::he38d6b4c3fc97d34
                    ┊                ┊    2238 ┊  0.02% ┊     combine::error::ParseResult<T,E>::map::h29ee1b27370bd849
                    ┊                ┊    2238 ┊  0.02% ┊     combine::error::ParseResult<T,E>::map::h54af03011c543d64
                    ┊                ┊    2238 ┊  0.02% ┊     combine::error::ParseResult<T,E>::map::h69ec4066cc33427f
                    ┊                ┊    1899 ┊  0.02% ┊     combine::error::ParseResult<T,E>::map::h06e3d8d50f41650a
                    ┊                ┊    1899 ┊  0.02% ┊     combine::error::ParseResult<T,E>::map::h1b5d49bf88574567
                    ┊                ┊  130897 ┊  1.30% ┊     ... and 97 more.
             129049 ┊          1.28% ┊  131868 ┊  1.31% ┊ combine::parser::ParseMode::parse_committed
                    ┊                ┊    2819 ┊  0.03% ┊     combine::parser::ParseMode::parse_committed::h059c6e4411be329d
                    ┊                ┊    2819 ┊  0.03% ┊     combine::parser::ParseMode::parse_committed::h44181ff20cda936b
                    ┊                ┊    2802 ┊  0.03% ┊     combine::parser::ParseMode::parse_committed::h13a5dc406df5fe3c
                    ┊                ┊    2802 ┊  0.03% ┊     combine::parser::ParseMode::parse_committed::h18e0ccd99be6f658
                    ┊                ┊    2802 ┊  0.03% ┊     combine::parser::ParseMode::parse_committed::haf78a2d671168063
                    ┊                ┊    2802 ┊  0.03% ┊     combine::parser::ParseMode::parse_committed::hbbb0c311d57c6898
                    ┊                ┊    2802 ┊  0.03% ┊     combine::parser::ParseMode::parse_committed::hcbfbeb6f46f421a7
                    ┊                ┊    2801 ┊  0.03% ┊     combine::parser::ParseMode::parse_committed::h2b28d8d08cb54796
                    ┊                ┊    2801 ┊  0.03% ┊     combine::parser::ParseMode::parse_committed::h3df69e66d7b10ce9
                    ┊                ┊    2801 ┊  0.03% ┊     combine::parser::ParseMode::parse_committed::h690859832a155bf0
                    ┊                ┊  103817 ┊  1.03% ┊     ... and 38 more.
             123454 ┊          1.22% ┊  136038 ┊  1.35% ┊ <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice
                    ┊                ┊   12584 ┊  0.12% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h025463a30180328d
                    ┊                ┊   12551 ┊  0.12% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::hd68134f10e1e4f01
                    ┊                ┊   12535 ┊  0.12% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h40ac7036cb0fd212
                    ┊                ┊   12501 ┊  0.12% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h3b63e0350b9b2a65
                    ┊                ┊   10558 ┊  0.10% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::hf4b8e2880aee7d41
                    ┊                ┊   10510 ┊  0.10% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::ha0572a9e971ccc08
                    ┊                ┊   10509 ┊  0.10% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h765bee9e224f921c
                    ┊                ┊    9178 ┊  0.09% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::hcc30478a83c8cdfa
                    ┊                ┊    9146 ┊  0.09% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::hedddaf4d72277679
                    ┊                ┊    9007 ┊  0.09% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h4467ca615c8f3c7e
                    ┊                ┊   26959 ┊  0.27% ┊     ... and 3 more.
              88253 ┊          0.87% ┊   91364 ┊  0.90% ┊ <combine::parser::repeat::Iter<Input,P,S,M> as core::iter::traits::iterator::Iterator>::next
                    ┊                ┊    3111 ┊  0.03% ┊     <combine::parser::repeat::Iter<Input,P,S,M> as core::iter::traits::iterator::Iterator>::next::he690ed6262fc4043
                    ┊                ┊    3053 ┊  0.03% ┊     <combine::parser::repeat::Iter<Input,P,S,M> as core::iter::traits::iterator::Iterator>::next::h7f55b769f2643b72
                    ┊                ┊    2859 ┊  0.03% ┊     <combine::parser::repeat::Iter<Input,P,S,M> as core::iter::traits::iterator::Iterator>::next::h1fca9ac07387e56f
                    ┊                ┊    2802 ┊  0.03% ┊     <combine::parser::repeat::Iter<Input,P,S,M> as core::iter::traits::iterator::Iterator>::next::hb26cdae557dc6699
                    ┊                ┊    2802 ┊  0.03% ┊     <combine::parser::repeat::Iter<Input,P,S,M> as core::iter::traits::iterator::Iterator>::next::hd98a178ff854b7d2
                    ┊                ┊    2624 ┊  0.03% ┊     <combine::parser::repeat::Iter<Input,P,S,M> as core::iter::traits::iterator::Iterator>::next::h85703e31d115a540
                    ┊                ┊    2608 ┊  0.03% ┊     <combine::parser::repeat::Iter<Input,P,S,M> as core::iter::traits::iterator::Iterator>::next::h9387159b211fc49e
                    ┊                ┊    2565 ┊  0.03% ┊     <combine::parser::repeat::Iter<Input,P,S,M> as core::iter::traits::iterator::Iterator>::next::h96fe7bc96a99202b
                    ┊                ┊    2550 ┊  0.03% ┊     <combine::parser::repeat::Iter<Input,P,S,M> as core::iter::traits::iterator::Iterator>::next::h36111f87c4e622fd
                    ┊                ┊    2550 ┊  0.03% ┊     <combine::parser::repeat::Iter<Input,P,S,M> as core::iter::traits::iterator::Iterator>::next::ha7e0bd922239c973
                    ┊                ┊   63840 ┊  0.63% ┊     ... and 32 more.
              78690 ┊          0.78% ┊   79300 ┊  0.79% ┊ combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}
                    ┊                ┊     610 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h00a71a5d08c0ddd1
                    ┊                ┊     610 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h00b7c5c41d2ebd5c
                    ┊                ┊     610 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h027f8b6c4ebff39d
                    ┊                ┊     610 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h0499bedcf0b5edc6
                    ┊                ┊     610 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h071800d758394969
                    ┊                ┊     610 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h0ccb7c920445c12a
                    ┊                ┊     610 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h0d5508f1e5132e74
                    ┊                ┊     610 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h1071bc05fffdf143
                    ┊                ┊     610 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h11fa54b65ed0114d
                    ┊                ┊     610 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h14094a7a53299d0d
                    ┊                ┊   73200 ┊  0.72% ┊     ... and 120 more.
              69848 ┊          0.69% ┊   70962 ┊  0.70% ┊ <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter
                    ┊                ┊    1114 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::h9a26d1ccef14cf07
                    ┊                ┊    1067 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::h158b228f50757ebd
                    ┊                ┊    1060 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::h14ee21ff34dc2973
                    ┊                ┊    1060 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::h25547edf4b7d8b53
                    ┊                ┊    1060 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::hb63b32b7cd661bcd
                    ┊                ┊     994 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::h987a2cac23e08b27
                    ┊                ┊     896 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::h034448b19e790178
                    ┊                ┊     896 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::h1ad9c26362163566
                    ┊                ┊     868 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::h67932d92a1996856
                    ┊                ┊     865 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::h29655b407710d009
                    ┊                ┊   61082 ┊  0.60% ┊     ... and 106 more.
            3446490 ┊         34.13% ┊ 5182387 ┊ 51.32% ┊ ... and 14733 more.
            5495997 ┊         54.43% ┊ 7285417 ┊ 72.15% ┊ Σ [14853 Total Rows]

but this is when i build for for dev/with debug symbols, the release build does not have any info.

a typical parser function look like this

fn function_param<Input>() -> impl Parser<Input, Output = FunctionParam>
where
    Input: Stream<Token = char>,
{
    choice!(
        function_call().map(|(fn_name, parameters)| FunctionParam::Func {fn_name, parameters}),
        field().map(FunctionParam::Fld),
        between(
            char('\''), 
            char('\''), 
            many::<String,_,_>(none_of("'".chars())),
        )
        .and(optional(cast()))
        .map(|(v,c)| FunctionParam::Val(SingleVal(v,c.clone()),c))
    )
}

I am leaving the output above only for reference, no need to investigate deeper, I just reached out in case there is some "easy fix" that you are aware of (and would require no effort on your part besides a short comment).

Thank you again for the awesome lib and your time. I'll post back in case i discover something interesting in this area

Marwes commented 2 years ago

You could try using the choice function, instead of the choice! macro. At a guess, it may generate less code.

Marwes commented 2 years ago

Found a s small improvement for sequence parsers https://github.com/Marwes/combine/pull/351 .

I also hacked in a way to disable partial parsing via a feature flag in this branch https://github.com/Marwes/combine/tree/no_default_partial which you could try to see if and how much of a difference it makes. Can't say if it is a good idea to add, but knowing if it helps or not would be necessary first.

klensy commented 2 years ago

Interesting results, @ruslantalpa !

How you build crate for use with twiggy? I've tried to build it with wasm32-unknown-unknown and cdylib crate type, but it given error like error: function or code section is missing. If i build it with wasm32-wasi it shows only debug sections with other ones as mostly zero sized.

ruslantalpa commented 2 years ago

@Marwes thank you, i will try both your suggestions (though in about 1-2 weeks) and report back the results. thank you again for looking into this.

@klensy I basically setup the project like this the main part in Cargo.toml is basically

[lib]
crate-type = ["cdylib", "rlib"]

and i build it with wasm-pack build --target nodejs --dev and run twiggy with twiggy monos pkg/mylib_wasm_bg.wasm basically the setup/build was done through wasm-pack (not just cargo build)

ruslantalpa commented 2 years ago

@Marwes tried your new branch (though had to fork it and change the TRY_PARTIAL to pub to get it to compile)

results are: in release i see not big size difference (probably due to LLVM optimizations) but in dev mode there is definitely some improvement, a bit in size but also in the twiggy output, at a glance, the number of total monomorphizations per combinator is about half.

I will try to have a deeper understanding of what's going on, try things out and will report back as a reference in case it helps inform future decisions.

Thank you for your time

Apprx. Bloat Bytes │ Apprx. Bloat % │ Bytes   │ %      │ Monomorphizations
────────────────────┼────────────────┼─────────┼────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
             339324 ┊          3.98% ┊  347800 ┊  4.08% ┊ combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl
                    ┊                ┊    8476 ┊  0.10% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::h6396f8787dfacfe9
                    ┊                ┊    8289 ┊  0.10% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::h22b80868cc2ea3e4
                    ┊                ┊    8289 ┊  0.10% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::hfd408300f9438e27
                    ┊                ┊    7646 ┊  0.09% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::hea7a7bf768046d74
                    ┊                ┊    7209 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::hb4f22902c68a49dd
                    ┊                ┊    6817 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::hb22cb869abbc3f66
                    ┊                ┊    6817 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::heb86ec65f0ef4e98
                    ┊                ┊    6798 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::h649520a40e8b3c69
                    ┊                ┊    6764 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::hc66905332ed9af29
                    ┊                ┊    6760 ┊  0.08% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B)>::parse_mode_impl::heecced7017142e35
                    ┊                ┊  273935 ┊  3.21% ┊     ... and 53 more.
             171665 ┊          2.01% ┊  181569 ┊  2.13% ┊ <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice
                    ┊                ┊    9904 ┊  0.12% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::hee09a3b143bfd6e1
                    ┊                ┊    9904 ┊  0.12% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::hf660b5f1ea17bedf
                    ┊                ┊    9523 ┊  0.11% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::hd22af87725c14213
                    ┊                ┊    9482 ┊  0.11% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::hd101adff3d3c29bf
                    ┊                ┊    9217 ┊  0.11% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::hb8baa9781fc55a99
                    ┊                ┊    8396 ┊  0.10% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::hcbcf4aacdb9eef13
                    ┊                ┊    7780 ┊  0.09% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h58d41b8e768d6731
                    ┊                ┊    7780 ┊  0.09% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h94653ee0988af49e
                    ┊                ┊    7776 ┊  0.09% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h31ddb63acae75fe9
                    ┊                ┊    7776 ┊  0.09% ┊     <(Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h52256be9e6732117
                    ┊                ┊   94031 ┊  1.10% ┊     ... and 14 more.
             105557 ┊          1.24% ┊  108535 ┊  1.27% ┊ <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl
                    ┊                ┊    2978 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::h40f67efa78bce29a
                    ┊                ┊    2978 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::h6ba405c27cc2a056
                    ┊                ┊    2546 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::hc3dd296adacb1a6b
                    ┊                ┊    2546 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::he851bc251fd038ae
                    ┊                ┊    2291 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::h2430f1dc3016d51a
                    ┊                ┊    2291 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::h8914d33835b0a2d1
                    ┊                ┊    2225 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::h28ef88c8e1ee01e5
                    ┊                ┊    2139 ┊  0.03% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::hf40016fb8d0a08b7
                    ┊                ┊    2058 ┊  0.02% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::ha36eb1a9b641def1
                    ┊                ┊    2058 ┊  0.02% ┊     <combine::parser::combinator::Map<P,F> as combine::parser::Parser<Input>>::parse_mode_impl::hbbdc71374246ca0b
                    ┊                ┊   84425 ┊  0.99% ┊     ... and 56 more.
              89530 ┊          1.05% ┊   92098 ┊  1.08% ┊ combine::error::ParseResult<T,E>::map
                    ┊                ┊    2568 ┊  0.03% ┊     combine::error::ParseResult<T,E>::map::h005010e08e35e54b
                    ┊                ┊    2568 ┊  0.03% ┊     combine::error::ParseResult<T,E>::map::haf011a08d52aaa65
                    ┊                ┊    2568 ┊  0.03% ┊     combine::error::ParseResult<T,E>::map::hf28fc3dbb182cb0a
                    ┊                ┊    2238 ┊  0.03% ┊     combine::error::ParseResult<T,E>::map::h8ffb184c660848ee
                    ┊                ┊    2238 ┊  0.03% ┊     combine::error::ParseResult<T,E>::map::hdd10f124d26f0b20
                    ┊                ┊    1899 ┊  0.02% ┊     combine::error::ParseResult<T,E>::map::h5b38563ef3e49aa9
                    ┊                ┊    1899 ┊  0.02% ┊     combine::error::ParseResult<T,E>::map::h9ec9328c1d12a9e5
                    ┊                ┊    1899 ┊  0.02% ┊     combine::error::ParseResult<T,E>::map::hf2c2a0e4163619b3
                    ┊                ┊    1580 ┊  0.02% ┊     combine::error::ParseResult<T,E>::map::h07dc034dd4a30fd5
                    ┊                ┊    1580 ┊  0.02% ┊     combine::error::ParseResult<T,E>::map::h234c472e15a336bb
                    ┊                ┊   71061 ┊  0.83% ┊     ... and 53 more.
              76125 ┊          0.89% ┊   76734 ┊  0.90% ┊ combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}
                    ┊                ┊     609 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h01458f6569ec674d
                    ┊                ┊     609 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h0154d96561f5e2dd
                    ┊                ┊     609 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h027fbd844b77fa6e
                    ┊                ┊     609 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h0528d7fa78e213f3
                    ┊                ┊     609 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h062793b44da19914
                    ┊                ┊     609 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h0737da6ee49161af
                    ┊                ┊     609 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h0dcd6e2cb3d91459
                    ┊                ┊     609 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h0dfcc79f2ec340fc
                    ┊                ┊     609 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h0e9cdc56f93f9868
                    ┊                ┊     609 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::{{closure}}::h1083f8fecfc02e4a
                    ┊                ┊   70644 ┊  0.83% ┊     ... and 116 more.
              72074 ┊          0.84% ┊   81060 ┊  0.95% ┊ combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl
                    ┊                ┊    8986 ┊  0.11% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::hcc570a066018f593
                    ┊                ┊    8022 ┊  0.09% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::h82326aa745533d98
                    ┊                ┊    8022 ┊  0.09% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::h948fd29698376eb8
                    ┊                ┊    8022 ┊  0.09% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::h9e06f626bc281a30
                    ┊                ┊    8022 ┊  0.09% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::hb6101c75a65d7f94
                    ┊                ┊    8022 ┊  0.09% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::hfe91b302a4212ab6
                    ┊                ┊    8021 ┊  0.09% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::hb1f8c84e850709c7
                    ┊                ┊    7981 ┊  0.09% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::h3d8512c3be127cbd
                    ┊                ┊    7981 ┊  0.09% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::hb1d35a2e3d4fb04c
                    ┊                ┊    7981 ┊  0.09% ┊     combine::parser::sequence::<impl combine::parser::Parser<Input> for (A,B,C)>::parse_mode_impl::hed09f39e72126aee
              69822 ┊          0.82% ┊   70936 ┊  0.83% ┊ <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter
                    ┊                ┊    1114 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::hbde2de38194ace0c
                    ┊                ┊    1067 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::haa0d2b306d5bfe60
                    ┊                ┊    1060 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::h031903dbb2921388
                    ┊                ┊    1060 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::h5c8cf0ba42d8df4a
                    ┊                ┊    1060 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::h6ca6a54e4b6aa8cd
                    ┊                ┊     994 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::h61d862e101f39c83
                    ┊                ┊     896 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::h9ef71e57ecf3fb88
                    ┊                ┊     896 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::hff14d616e902e74f
                    ┊                ┊     867 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::h2eae3a1b4047c8bb
                    ┊                ┊     865 ┊  0.01% ┊     <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::h82126b6b2f116255
                    ┊                ┊   61057 ┊  0.72% ┊     ... and 106 more.
              60884 ┊          0.71% ┊   61866 ┊  0.73% ┊ combine::parser::sequence::PartialState2<A,B>::add_errors
                    ┊                ┊     982 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::h0362af5b61e1b1a1
                    ┊                ┊     982 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::h043bb98de836821c
                    ┊                ┊     982 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::h053f5283c74ef253
                    ┊                ┊     982 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::h07998417fdfc99b7
                    ┊                ┊     982 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::h0b1ed2bafa14655c
                    ┊                ┊     982 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::h12c3763dd26fffae
                    ┊                ┊     982 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::h15a152cf99864a9a
                    ┊                ┊     982 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::h17f542bf7853baa2
                    ┊                ┊     982 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::h1cb2182b3c8dfe9d
                    ┊                ┊     982 ┊  0.01% ┊     combine::parser::sequence::PartialState2<A,B>::add_errors::h208df2d9cfc5c8ff
                    ┊                ┊   52046 ┊  0.61% ┊     ... and 53 more.
              60585 ┊          0.71% ┊   73113 ┊  0.86% ┊ <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice
                    ┊                ┊   12528 ┊  0.15% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::heba0ee191a3134f6
                    ┊                ┊   12494 ┊  0.15% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::hfd39ffd87d940c76
                    ┊                ┊   10503 ┊  0.12% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h1e57c9478d3599fc
                    ┊                ┊   10502 ┊  0.12% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h751e5ec41b944232
                    ┊                ┊    9142 ┊  0.11% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h2f49973d33a8ef4a
                    ┊                ┊    8972 ┊  0.11% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h5d4aeaaa0aa5d7b2
                    ┊                ┊    8972 ┊  0.11% ┊     <(X,Y,Z) as combine::parser::choice::ChoiceParser<Input>>::parse_mode_choice::h86a820b668fb09d8
              58422 ┊          0.68% ┊   59278 ┊  0.69% ┊ alloc::vec::Vec<T,A>::extend_desugared
                    ┊                ┊     856 ┊  0.01% ┊     alloc::vec::Vec<T,A>::extend_desugared::h43de37b68438f095
                    ┊                ┊     856 ┊  0.01% ┊     alloc::vec::Vec<T,A>::extend_desugared::h6720d62762b25cfa
                    ┊                ┊     856 ┊  0.01% ┊     alloc::vec::Vec<T,A>::extend_desugared::hc290e410e1591981
                    ┊                ┊     846 ┊  0.01% ┊     alloc::vec::Vec<T,A>::extend_desugared::hcbc9bc32a508605b
                    ┊                ┊     825 ┊  0.01% ┊     alloc::vec::Vec<T,A>::extend_desugared::had28742e1327bf54
                    ┊                ┊     825 ┊  0.01% ┊     alloc::vec::Vec<T,A>::extend_desugared::hb01d11b964038a8f
                    ┊                ┊     803 ┊  0.01% ┊     alloc::vec::Vec<T,A>::extend_desugared::h48e52b8a47df8720
                    ┊                ┊     803 ┊  0.01% ┊     alloc::vec::Vec<T,A>::extend_desugared::h5d2badcca9c8e8ae
                    ┊                ┊     801 ┊  0.01% ┊     alloc::vec::Vec<T,A>::extend_desugared::h5c321d01eb3dbeb4
                    ┊                ┊     794 ┊  0.01% ┊     alloc::vec::Vec<T,A>::extend_desugared::h1419983db15b3ccf
                    ┊                ┊   51013 ┊  0.60% ┊     ... and 82 more.
            3063813 ┊         35.91% ┊ 4799895 ┊ 56.26% ┊ ... and 14625 more.
            4167801 ┊         48.85% ┊ 5952884 ┊ 69.78% ┊ Σ [14740 Total Rows]