Improve compilation speed by taking advantage of memoization
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 35/100
- Issue type
- Refactor
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- cpp
- Domain
- performance
Research direction
Start in boost/mp11/map.hpp, focusing on mp_map_find_impl and the related repeated patterns described in the issue. Use the supplied C++ benchmark with /usr/bin/time on Linux to compare compilation time and memory before and after. Done means reducing duplicated template instantiation work while preserving the existing map behavior and confirming the reported measurements.
Written by the indexing model from the issue text.
Description
Mp11 does not take full advantage of memoization, which increases compile time and memory usage.
For example for mp_map_find_impl:
template<template<class...> class M, class... T, class K> struct mp_map_find_impl<M<T...>, K>
{
using U = mp_inherit<mpmf_wrap<T>...>;
template<template<class...> class L, class... U> static mp_identity<L<K, U...>> f( mp_identity<L<K, U...>>* );
static mp_identity<void> f( ... );
using type = mpmf_unwrap< decltype( f((U*)0) ) >;
};
Here, the function f is duplicated as many times as there are instantiations of mp_map_find_impl. but, f depends only on K, not on M, nor on T. Moving the functions into a separate structure that takes K allows it not to be duplicated.
Example:
template<class K> struct mp_map_find_key
{
template<template<class...> class L, class... U> static mp_identity<L<K, U...>> f( mp_identity<L<K, U>
static mp_identity<void> f( ... );
};
template<template<class...> class M, class... T, class K> struct mp_map_find_impl<M<T...>, K>
{
using U = mp_inherit<mpmf_wrap<T>...>;
using type = mpmf_unwrap< decltype( mp_map_find_key<K>::f((U*)0) ) >;
};
Here is the before/after result (measured with /usr/bin/time --format='%Es - %MK' on Linux)
| compiler | gcc-12 | clang-15 |
|---|---|---|
| before | 0:00.46s - 200544K | 0:00.45s - 159492K |
| after | 0:00.37s - 172132K | 0:00.43s - 156836K |
The test code:
#include <boost/mp11/map.hpp>
using namespace boost::mp11;
using numbers = mp_iota_c<100>;
using l1 = mp_transform<mp_list, mp_append<numbers, numbers>>;
using l2 = mp_append<mp_list<mp_list<mp_size_t<2>>>, l1>;
using l3 = mp_append<mp_list<mp_list<mp_size_t<3>>>, l1>;
using l4 = mp_append<mp_list<mp_list<mp_size_t<4>>>, l1>;
using l5 = mp_append<mp_list<mp_list<mp_size_t<5>>>, l1>;
using m1 = mp_fold<l1, mp_list<>, mp_map_insert>;
using m2 = mp_fold<l2, mp_list<>, mp_map_insert>;
using m3 = mp_fold<l3, mp_list<>, mp_map_insert>;
using m4 = mp_fold<l4, mp_list<>, mp_map_insert>;
using m5 = mp_fold<l5, mp_list<>, mp_map_insert>;
I noticed this pattern several times, but the changes are minor compared to the benefit (especially with gcc).
- Dominant language
- C++
- Stars
- 291
- Forks
- 97
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from boostorg/mp11
-
Difficulty 3/5 1-2 days Newbie friendliness 52/100
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
-
Difficulty 4/5 3-5 days Newbie friendliness 38/100
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 35/100
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
AXERA-TECH/ax-llm#77 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
games-on-whales/wolf#509 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
bug-unconfirmed
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
NVIDIA/cuda-samples#453 ·