从reddit/hackernews/lobsters/meetingcpp摘抄一些c++动态
周刊项目地址|在线地址 |知乎专栏 | 腾讯云+社区 |
欢迎投稿,推荐或自荐文章/软件/资源等,请提交 issue
标准委员会动态/ide/编译器信息放在这里
编译器信息最新动态推荐关注hellogcc公众号 本周更新 2022-03-02 第139期
数字转字符串 sprintf性能,非常垃圾,使用fmt
或者std::to_chars
namespace adl {
struct foo {};
void bar(foo) {}
}
int main() {
adl::foo foo;
bar(foo); // OK, ADL
(bar)(foo); // error: no ADL
}
就是名字空间内的查找
#include <utility>
int main() {
std::unreachable();
return 42; // invokes undefined behavior
}
没啥说的,类似assert(false)
int main() {
std::vector v{1, 2, 3, 4};
assert(4 == std::size(v));
std::erase_if(v, [](const auto& e) { return e % 2;} );
assert(2 == std::size(v));
assert(v[0] == 2 and v[1] == 4);
}
没啥说的
手把手教你图像过滤,看不懂
图像sample 看不懂
手把手教你gmock
几个需求,编译期打印字符串,编译期生成随机数 第一个简单,就是fixed_string+static assert
struct ct_str
{
char _data[512]{};
std::size_t _size{0};
template <std::size_t N>
constexpr ct_str(const char (&str)[N]) : _data{}, _size{N - 1}
{
for(std::size_t i = 0; i < _size; ++i)
_data[i] = str[i];
}
};
template <ct_str> struct print;
constexpr ct_str test()
{
ct_str s{"Welcome to Wordlexpr!"};
s._data[0] = 'w';
s._data[11] = 'w';
s._data[20] = '.';
return s;
}
print<test()> _{};
第二个就是用fixed_string来做生成随机数的生成器,让外部指定seed和字符串,然后编译的时候改一改就行了
语言律师新活,如果itor是T*,会有一大堆冲突问题,后面是一大堆列举。这里不提了
感谢@LH_Mouse 纠正。这里指的是是实现的不可见导致的开销。实现的不可见(不内联场景),编译器可能假定抛出异常,假定不是const。所以这里不是zero cost。即使你不用异常也会有类似的问题
c++编译依赖和头文件的问题。属于老生常谈的讨论
google benchmark教程,几个案例
基本的阻止优化
static void i32_addition_semirandom(bm::State &state) {
int32_t a = std::rand(), b = std::rand(), c = 0;
for (auto _ : state)
bm::DoNotOptimize(c = (++a) + (++b));
}
一个简单的数学算法对比
static void f64_sin(bm::State &state) {
double argument = std::rand(), result = 0;
for (auto _ : state)
bm::DoNotOptimize(result = std::sin(argument += 1.0));
}
static void f64_sin_maclaurin(bm::State &state) {
double argument = std::rand(), result = 0;
for (auto _ : state) {
argument += 1.0;
result = argument - std::pow(argument, 3) / 6 + std::pow(argument, 5) / 120;
bm::DoNotOptimize(result);
}
}
static void f64_sin_maclaurin_powless(bm::State &state) {
double argument = std::rand(), result = 0;
for (auto _ : state) {
argument += 1.0;
result = argument - (argument * argument * argument) / 6.0 +
(argument * argument * argument * argument * argument) / 120.0;
bm::DoNotOptimize(result);
}
}
[[gnu::optimize("-ffast-math")]]
static void f64_sin_maclaurin_with_fast_math(bm::State &state) {
double argument = std::rand(), result = 0;
for (auto _ : state) {
argument += 1.0;
result = argument - (argument * argument * argument) / 6.0 +
(argument * argument * argument * argument * argument) / 120.0;
bm::DoNotOptimize(result);
}
}
注意这个attrbute用法。最后一种非常快
整数除法
static void i64_division(bm::State &state) {
int64_t a = std::rand(), b = std::rand(), c = 0;
for (auto _ : state)
bm::DoNotOptimize(c = (++a) / (++b));
}
static void i64_division_by_const(bm::State &state) {
int64_t money = 2147483647;
int64_t a = std::rand(), c;
for (auto _ : state)
bm::DoNotOptimize(c = (++a) / *std::launder(&money));
}
static void i64_division_by_constexpr(bm::State &state) {
constexpr int64_t b = 2147483647;
int64_t a = std::rand(), b;
for (auto _ : state)
bm::DoNotOptimize(c = (++a) / b);
}
constexpr非常快
硬件加速
[[gnu::target("default")]] static void u64_population_count(bm::State &state) {
auto a = static_cast<uint64_t>(std::rand());
for (auto _ : state)
bm::DoNotOptimize(__builtin_popcount(++a));
}
[[gnu::target("popcnt")]] static void u64_population_count_x86(bm::State &state) {
auto a = static_cast<uint64_t>(std::rand());
for (auto _ : state)
bm::DoNotOptimize(__builtin_popcount(++a));
}
如果硬件支持popcnt指令,有优化提升
里面有个表格概括,就不截图了
还是模板 + fixed_string/array 这种场景,如果fixed_string/array是相同的,由于模板实例化相同的实例会合并,所以说这就是一种压缩效果,复用数据段。
就是static assert + type traits没啥说的
又介绍个parser generator