├── README.md ├── run.sh ├── .gitignore ├── .travis.yml ├── main.cpp └── CMakeLists.txt /README.md: -------------------------------------------------------------------------------- 1 | # check_compile_times 2 | Check various boost headers impact on the compilation time. 3 | 4 | Auto-generated and measured via Travis-CI, latest results may be found on [wiki](https://github.com/MKlimenko/check_compile_times/wiki). -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | conan install boost/1.76.0@ --build=never -if build/boost -s build_type=Debug -g CMakeDeps 2 | cd build 3 | 4 | for i in {0..9} 5 | do 6 | mkdir build_$i 7 | cd build_$i 8 | cmake -G Ninja ../.. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=$PWD/../boost 9 | cmake --build . 10 | cd .. 11 | done 12 | 13 | cmake -G Ninja .. -DSKIP_EVALUATION=true -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=$PWD/boost 14 | cmake --build . 15 | ./CheckCompileTimes 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | #Ignore thumbnails created by Windows 3 | Thumbs.db 4 | #Ignore files built by Visual Studio 5 | *.obj 6 | *.exe 7 | *.pdb 8 | *.user 9 | *.aps 10 | *.pch 11 | *.vspscc 12 | *_i.c 13 | *_p.c 14 | *.ncb 15 | *.suo 16 | *.tlb 17 | *.tlh 18 | *.bak 19 | *.cache 20 | *.ilk 21 | *.log 22 | [Bb]in 23 | [Dd]ebug*/ 24 | *.lib 25 | *.sbr 26 | obj/ 27 | [Rr]elease*/ 28 | _ReSharper*/ 29 | [Tt]est[Rr]esult* 30 | .vs/ 31 | #Nuget packages folder 32 | packages/ 33 | /build/* 34 | /boost-*-hpp_main.cpp 35 | 36 | *_main.cpp 37 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | os: linux 3 | dist: focal 4 | compiler: 5 | - clang 6 | addons: 7 | apt: 8 | packages: 9 | - clang-10 10 | - libc++-10-dev 11 | - libc++abi-10-dev 12 | - libtbb-dev 13 | - ninja-build 14 | before_install: 15 | - eval "CC=clang-10 && CXX=clang-10" 16 | - pip install conan 17 | - conan install boost/1.76.0@ --build=never -if build/boost -s build_type=Debug -g CMakeDeps 18 | script: 19 | - cd build 20 | - | 21 | for i in {0..9} 22 | do 23 | mkdir build_$i; 24 | cd build_$i; 25 | cmake -G Ninja ../.. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=$PWD/../boost; 26 | cmake --build .; 27 | cd ..; 28 | done 29 | - cmake -G Ninja .. -DSKIP_EVALUATION=true -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=$PWD/boost 30 | - cmake --build . 31 | - git clone https://github.com/MKlimenko/check_compile_times.wiki.git 32 | - "./CheckCompileTimes" 33 | - cd check_compile_times.wiki 34 | - git config user.name "Michael Klimenko" 35 | - git config user.email "mklimenko29@gmail.com" 36 | - git add Home.md 37 | - git commit -m "Update table" 38 | - git remote remove origin 39 | - git remote add origin https://$GITHUB_API_KEY@github.com/MKlimenko/check_compile_times.wiki.git 40 | - git remote add upstream https://$GITHUB_API_KEY@github.com/MKlimenko/check_compile_times.wiki.git 41 | - git fetch origin 42 | - git fetch upstream 43 | - git merge upstream/master --no-edit 44 | - git push origin HEAD:master 45 | - git push upstream HEAD:master 46 | env: 47 | matrix: 48 | secure: wmfHCm2jtv3AxSRGo3je0EyMy/QLO5oo/bj+JicVctjRdBt5+88khL1lG5HeRtfROtnzVXh5ki0nl5FSo+V2JcAOEdlMIUOd1jup/zNK2zts12Kcc21sT2SAQRqa5KslK0u40p8i5ZvGxK2KKC2uUu7EHlu5a05mD+C67xPaHKLafRPs+fobb4R5BJIZkycI2C/bVeq8S/18BlHicmATSaogDQikwuauGUGAkGd8aJvXy7IsogGC40o5l9A4a/4EvpHWWOEPOebBqmTbHHxz0f9dnL9eYtS147oTHCw5M87QuL9uWZyw4M5SeugbZDR2zihrcSOyPSdIHlkOaWy0gd5WZFhFf9FE9GrxNe4XmMN8wqcy1zADvFWV9ppQLUqATN328Us/neMSP+60YEYajXpyl3sE+fupvQYOTX6lnMspJ2xhzgMJELKsYVilLOzfZY1beqsiH//diXkarZA00QjySI4tFEHvkIlRwtMsgp9A08n89Kd2+jTc7nJx/uPLN3SraLoT8dS+EO99J/PNFCR+idiW5OZ/yGSap2nN05Cy0xtKOvPoeb/SlAEK/WyRh58bDMIf0CywJGZQpDBjxNmXurWPDfkNaBzo5ZStlMwhTsY5aeppNgdFC/3O0Wdg5HW9uB0nnqZXr3xtHo3USaAak485HZ3Ta914rEyUziU= 49 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace { 12 | std::map> header_time_map; 13 | 14 | void GetElapsedTime(const std::filesystem::path& json_file) { 15 | auto filename = std::filesystem::path(json_file).filename().string(); 16 | auto boost_ending = filename.find("-hpp_main.cpp.json"); 17 | if (boost_ending == std::string::npos) 18 | filename.resize(filename.find("_main.cpp.json")); 19 | else { 20 | filename.resize(boost_ending); 21 | std::replace(filename.begin(), filename.end(), '-', '/'); 22 | filename += ".hpp"; 23 | } 24 | 25 | std::ifstream json_stream(json_file); 26 | auto str = std::string((std::istreambuf_iterator(json_stream)), std::istreambuf_iterator()); 27 | 28 | auto offset = str.find("avg ms"); 29 | str = str.substr(offset + 8); 30 | str.resize(str.find('}')); 31 | auto elapsed = std::atof(str.c_str()); 32 | 33 | header_time_map[filename].push_back(elapsed); 34 | } 35 | 36 | template 37 | void PrintTop5(const std::string& name, T& vector, double baseline, std::ostream& table) { 38 | std::partial_sort(vector.begin(), vector.begin() + std::min(static_cast(vector.size()), 5), vector.end(), [](auto&lhs, auto&rhs) { 39 | return lhs.second > rhs.second; 40 | }); 41 | 42 | table << "# Top-5 " << name << " headers compilation impact" << std::endl; 43 | table << "| Header | Time, ms | Relative slowdown |" << std::endl; 44 | table << "|- |- |- |" << std::endl; 45 | for (std::size_t i = 0; i < std::min(static_cast(vector.size()), 5); ++i) 46 | table << "|" << vector[i].first << "\t|" << vector[i].second << "\t|" << vector[i].second / baseline << "\t|" << std::endl; 47 | 48 | table << std::endl << std::endl << std::endl; 49 | } 50 | 51 | template 52 | void PrintTable(const std::string& name, T& vector, double baseline, std::ostream& table) { 53 | std::sort(vector.begin(), vector.end(), [](auto&lhs, auto&rhs) { 54 | return lhs.first < rhs.first; 55 | }); 56 | 57 | table << "# " << name << " headers compilation impact" << std::endl; 58 | 59 | table << "| Header | Time, ms | Relative slowdown |" << std::endl; 60 | table << "|- |- |- |" << std::endl; 61 | 62 | 63 | for (auto& el : vector) 64 | table << "|" << el.first << "\t|" << el.second << "\t|" << el.second / baseline << "\t|" << std::endl; 65 | 66 | table << std::endl << std::endl << std::endl; 67 | } 68 | } 69 | 70 | 71 | int main(int argc, char** argv) { 72 | try { 73 | auto files_path = std::filesystem::absolute(std::filesystem::path(argv[0]).remove_filename()); 74 | 75 | for (auto build : std::filesystem::directory_iterator(files_path)) { 76 | auto build_path = std::filesystem::path(build) / "CMakeFiles"; 77 | 78 | if (!std::filesystem::exists(build_path)) 79 | continue; 80 | 81 | for (auto& el : std::filesystem::directory_iterator(build_path)) { 82 | if (!std::filesystem::is_directory(el)) 83 | continue; 84 | 85 | 86 | if (std::filesystem::path(el).string().find(".dir") == std::string::npos) 87 | continue; 88 | 89 | for (auto& el_file : std::filesystem::directory_iterator(el)) { 90 | if (std::filesystem::path(el_file).extension().string() == ".json") { 91 | GetElapsedTime(el_file); 92 | } 93 | } 94 | } 95 | } 96 | 97 | auto markdown_table = std::ofstream("check_compile_times.wiki/Home.md"); 98 | std::ostream* table_ptr = &std::cout; 99 | if (markdown_table.is_open()) 100 | table_ptr = &markdown_table; 101 | 102 | std::vector> sorted_times_stl; 103 | std::vector> sorted_times_boost; 104 | double baseline = -1; 105 | for (auto& el : header_time_map) { 106 | auto time = std::accumulate(el.second.begin(), el.second.end(), 0.0); 107 | time /= el.second.size(); 108 | if (el.first.find("baseline") != std::string::npos) 109 | baseline = time; 110 | 111 | if (el.first.find("boost") != std::string::npos) 112 | sorted_times_boost.emplace_back(el.first, time); 113 | else 114 | sorted_times_stl.emplace_back(el.first, time); 115 | } 116 | 117 | PrintTop5("STL", sorted_times_stl, baseline, *table_ptr); 118 | PrintTop5("Boost", sorted_times_boost, baseline, *table_ptr); 119 | PrintTable("STL", sorted_times_stl, baseline, *table_ptr); 120 | PrintTable("Boost", sorted_times_boost, baseline, *table_ptr); 121 | } 122 | catch (std::exception& e) { 123 | std::cerr << e.what() << std::endl; 124 | } 125 | 126 | return 0; 127 | } 128 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | project(CheckCompileTimes LANGUAGES CXX) 3 | set(CMAKE_CXX_STANDARD 17) 4 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 5 | 6 | find_package(Boost 1.76.0 REQUIRED) 7 | 8 | if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 9 | message( FATAL_ERROR "Only clang currently supports -ftime-trace" ) 10 | endif() 11 | 12 | set(HEADERS_TO_PROCESS 13 | algorithm 14 | any 15 | array 16 | atomic 17 | bitset 18 | cassert 19 | cctype 20 | cerrno 21 | cfenv 22 | cfloat 23 | charconv 24 | chrono 25 | cinttypes 26 | climits 27 | clocale 28 | cmath 29 | codecvt 30 | complex 31 | condition_variable 32 | csetjmp 33 | csignal 34 | cstdarg 35 | cstddef 36 | cstdint 37 | cstdio 38 | cstdlib 39 | cstring 40 | ctime 41 | cuchar 42 | cwchar 43 | cwctype 44 | deque 45 | exception 46 | execution 47 | filesystem 48 | forward_list 49 | fstream 50 | functional 51 | future 52 | initializer_list 53 | iomanip 54 | ios 55 | iosfwd 56 | iostream 57 | istream 58 | iterator 59 | limits 60 | list 61 | locale 62 | map 63 | memory 64 | memory_resource 65 | mutex 66 | new 67 | numeric 68 | optional 69 | ostream 70 | queue 71 | random 72 | ratio 73 | regex 74 | scoped_allocator 75 | set 76 | shared_mutex 77 | sstream 78 | stack 79 | stdexcept 80 | streambuf 81 | string 82 | string_view 83 | strstream 84 | system_error 85 | thread 86 | tuple 87 | type_traits 88 | typeindex 89 | typeinfo 90 | unordered_map 91 | unordered_set 92 | utility 93 | valarray 94 | variant 95 | vector 96 | boost/accumulators/accumulators.hpp 97 | boost/algorithm/algorithm.hpp 98 | boost/align.hpp 99 | boost/any.hpp 100 | boost/array.hpp 101 | boost/asio.hpp 102 | boost/assert.hpp 103 | boost/assign.hpp 104 | boost/atomic.hpp 105 | boost/beast.hpp 106 | boost/bimap.hpp 107 | boost/bind/bind.hpp 108 | boost/call_traits.hpp 109 | boost/callable_traits.hpp 110 | boost/chrono.hpp 111 | boost/circular_buffer.hpp 112 | boost/compressed_pair.hpp 113 | boost/concept_check.hpp 114 | boost/config.hpp 115 | boost/container/flat_map.hpp 116 | boost/container/flat_set.hpp 117 | boost/container/slist.hpp 118 | boost/container/small_vector.hpp 119 | boost/container/stable_vector.hpp 120 | boost/container/static_vector.hpp 121 | boost/container_hash/hash.hpp 122 | boost/contract.hpp 123 | boost/convert.hpp 124 | boost/coroutine/all.hpp 125 | boost/coroutine2/all.hpp 126 | boost/crc.hpp 127 | boost/date_time.hpp 128 | boost/dll.hpp 129 | boost/dynamic_bitset.hpp 130 | boost/exception/all.hpp 131 | boost/fiber/all.hpp 132 | boost/filesystem.hpp 133 | boost/flyweight.hpp 134 | boost/foreach.hpp 135 | boost/format.hpp 136 | boost/function.hpp 137 | boost/function_types/function_type.hpp 138 | boost/functional.hpp 139 | boost/fusion/sequence.hpp 140 | boost/geometry.hpp 141 | boost/gil.hpp 142 | boost/graph/graph_traits.hpp 143 | boost/hana.hpp 144 | boost/heap/pairing_heap.hpp 145 | boost/histogram.hpp 146 | boost/hof.hpp 147 | boost/icl/interval.hpp 148 | boost/integer.hpp 149 | boost/intrusive_ptr.hpp 150 | boost/iterator.hpp 151 | boost/json.hpp 152 | boost/lambda/lambda.hpp 153 | boost/lexical_cast.hpp 154 | boost/local_function.hpp 155 | boost/locale.hpp 156 | boost/lockfree/queue.hpp 157 | boost/log/core/core.hpp 158 | boost/metaparse.hpp 159 | boost/multi_array.hpp 160 | boost/multi_index_container.hpp 161 | boost/multiprecision/integer.hpp 162 | boost/numeric/interval.hpp 163 | boost/operators.hpp 164 | boost/optional.hpp 165 | boost/outcome.hpp 166 | boost/parameter.hpp 167 | boost/pfr.hpp 168 | boost/phoenix.hpp 169 | boost/poly_collection/any_collection.hpp 170 | boost/polygon/polygon.hpp 171 | boost/pool/pool.hpp 172 | boost/preprocessor.hpp 173 | boost/process.hpp 174 | boost/program_options.hpp 175 | boost/property_map/property_map.hpp 176 | boost/property_tree/ptree.hpp 177 | boost/proto/proto.hpp 178 | boost/qvm/all.hpp 179 | boost/random.hpp 180 | boost/range.hpp 181 | boost/ratio.hpp 182 | boost/rational.hpp 183 | boost/ref.hpp 184 | boost/regex.hpp 185 | boost/safe_numerics/safe_integer.hpp 186 | boost/scope_exit.hpp 187 | boost/serialization/serialization.hpp 188 | boost/signals2.hpp 189 | boost/smart_ptr.hpp 190 | boost/sort/sort.hpp 191 | boost/spirit/home/x3.hpp 192 | boost/spirit/include/classic.hpp 193 | boost/spirit/include/qi.hpp 194 | boost/stacktrace.hpp 195 | boost/statechart/state.hpp 196 | boost/static_assert.hpp 197 | boost/swap.hpp 198 | boost/system/config.hpp 199 | boost/thread.hpp 200 | boost/throw_exception.hpp 201 | boost/timer/timer.hpp 202 | boost/tokenizer.hpp 203 | boost/tti/tti.hpp 204 | boost/tuple/tuple.hpp 205 | boost/type_erasure/any.hpp 206 | boost/type_index.hpp 207 | boost/type_traits.hpp 208 | boost/typeof/typeof.hpp 209 | boost/units/unit.hpp 210 | boost/unordered_map.hpp 211 | boost/unordered_set.hpp 212 | boost/utility.hpp 213 | boost/uuid/uuid.hpp 214 | boost/variant.hpp 215 | boost/vmd/vmd.hpp 216 | boost/wave.hpp 217 | boost/xpressive/xpressive.hpp 218 | boost/yap/yap.hpp 219 | ) 220 | 221 | if (NOT SKIP_EVALUATION) 222 | foreach(header ${HEADERS_TO_PROCESS}) 223 | string(REPLACE "." "-" filename_preliminary ${header}) 224 | string(REPLACE "/" "-" header_name ${filename_preliminary}) 225 | set(filename "${CMAKE_CURRENT_LIST_DIR}/${header_name}_main.cpp") 226 | list(APPEND sources ${filename}) 227 | file(WRITE ${filename} "#include <${header}>\n ") 228 | endforeach() 229 | 230 | set(filename "${CMAKE_CURRENT_LIST_DIR}/baseline-hpp_main.cpp") 231 | list(APPEND sources ${filename}) 232 | file(WRITE ${filename} "int main() { return 0; }\n") 233 | 234 | set(executable_name "CheckHeaders") 235 | add_executable(${executable_name} ${sources}) 236 | target_compile_options(${executable_name} PUBLIC -ftime-trace) 237 | target_link_libraries(${executable_name} pthread stdc++ stdc++fs tbb ${CONAN_LIBS}) 238 | target_include_directories(${executable_name} PUBLIC ${Boost_INCLUDE_DIRS}) 239 | endif() 240 | 241 | add_executable(CheckCompileTimes main.cpp) 242 | target_link_libraries(CheckCompileTimes stdc++ stdc++fs) 243 | target_compile_definitions(CheckCompileTimes PUBLIC CACHE_DIR="${CMAKE_CACHEFILE_DIR}") 244 | --------------------------------------------------------------------------------