mirror of
https://github.com/scylladb/scylladb.git
synced 2026-05-12 19:02:12 +00:00
When a template is instantiated in a header file which is included by many source files, the compiler needs to compile it again and again. ClangBuildAnalyzer helps find the worst cases of this happening, and one of the worst happens to be seastar::throw_with_backtrace<marshal_exception, sstring> This specific template function takes (according to ClangBuildAnalyzer) 362 milliseconds to instantiate, and this is done 312 (!) times, because it reaches virtually every Scylla source file via either types.hh or compound.hh which use this idiom. Unfortunately, C++ as it exists today does not have a mechanism to avoid compiling a specific template instantiation if this was already done in some other source file. But we can do this manually using the C++11 feature of "extern template": 1. For a specific template instance, in this case seastar::throw_with_backtrace<marhsal_exception, sstring>, all source files except one specify it as "extern template". This means that the code for it will NOT be built in this source file, and the compiler assumes the linker will eventually supply it. 2. At the same time, one source file instantiates this template instance once regularly, without "extern". The numbers from ClangBuildAnalyzer suggest that this patch should reduce total build time by 1% (in dev build mode), but this is hard to measure in practice because the very long build time (210 CPU minutes on my laptop) usually fluctuates by more than 1% in consecutive runs. However, we've seen in the past that a good estimate of build time is the total produced object size (du -bc build/dev/**/*.o). This patch indeed reduces this total object size (in dev build mode) by exactly 1%. Signed-off-by: Nadav Har'El <nyh@scylladb.com> Message-Id: <20220105171453.308821-1-nyh@scylladb.com>
44 lines
1.5 KiB
C++
44 lines
1.5 KiB
C++
/*
|
|
* Copyright (C) 2017-present ScyllaDB
|
|
*/
|
|
|
|
/*
|
|
* This file is part of Scylla.
|
|
*
|
|
* Scylla is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Scylla is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Scylla. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <stdexcept>
|
|
#include <seastar/core/sstring.hh>
|
|
|
|
#include "seastarx.hh"
|
|
|
|
class marshal_exception : public std::exception {
|
|
sstring _why;
|
|
public:
|
|
marshal_exception() = delete;
|
|
marshal_exception(sstring why) : _why(sstring("marshaling error: ") + why) {}
|
|
virtual const char* what() const noexcept override { return _why.c_str(); }
|
|
};
|
|
|
|
// Speed up compilation of code using throw_with_backtrace<marshal_exception,
|
|
// sstring> by compiling it only once (in types.cc), and elsewhere say that
|
|
// it is extern and not compile it again.
|
|
namespace seastar {
|
|
template <class Exc, typename... Args> [[noreturn]] void throw_with_backtrace(Args&&... args);
|
|
extern template void throw_with_backtrace<marshal_exception, sstring>(sstring&&);
|
|
}
|