周刊项目地址[1]
RSS https://github.com/wanghenshui/cppweeklynews/releases.atom
欢迎投稿,推荐或自荐文章/软件/资源等
请提交 issue[3]
感谢 不语 赞助
最近在找工作准备面试题,更新可能有些拖沓,见谅
以后可能要改变一下内容
一周发文章总结,一周发视频总结,这样两种内容交叉一下
本期发视频总结
资讯
标准委员会动态/ide/编译器信息放在这里
编译器信息最新动态推荐关注hellogcc公众号 OSDT Weekly 2023-10-25 第225期
视频
CPPNorth去年的讲一下。今年的PPT没全放出来
Amir Kirsh - Are your Structures Bindable
怎么检测一个类型是否能结构化展开?structure_bindale?
这也是一个SO上的提问 https://stackoverflow.com/questions/63369361/how-to-define-a-concept-of-a-object-that-is-can-be-structured-binding
代码在 https://godbolt.org/z/ocox9sqed
不知道什么场景能用上。看一乐
Amir Kirsh - The fine details behind C containers and algorithms
一些容器使用上的经验/坑
vector push_back的T有三种场景
- • trivially copyable 直接memcopy
- • nothrow_move_constructible 直接move 这就要求T的move构造要noexcept
- • 拷贝构造
std::copy 可能mommove 可能for循环无优化,注意使用
list原地sort通常不如拷贝到vector再sort 数据局部性问题
开头插入,list还是vector都不如 reserve预留空间 push_back 反转 reverse 快
尽可能降低挪动
https://quick-bench.com/q/Cx35L5th0bsvDMVHCdK61g08_z4 这个思路还是挺有意思的
按照index下标erase vector的优化,可以通过move来代替erase,最后只erase一次
这里index是降序的
代码语言:javascript复制size_t removed = 0;
for(auto index: indices_to_erase) { // indices_to_erase are sorted in descending order
std::move(vec.begin() index 1, vec.end() - removed, vec.begin() index);
removed;
}
vec.erase(vec.end() - removed, vec.end());
降低交换次数,move相当于交换 移动,减少拷贝,删除的越多,收益越大
如果index数组是升序的,怎么写?
unordered_map的优化
尽可能用insert_or_assign,比赋值快
https://stackoverflow.com/questions/63041408/unordered-map-excess-calls-to-hash-function
计算hash过于频繁
我觉得还是别用这破玩意了
try_emplace提高性能,这个之前咱们也提过,但一定要用对,不然可能性能下降。或者装作不知道这个函数吧
另外删改写回场景c 17可以通过extract node insert node实现,性能更好一些
https://quick-bench.com/q/QtFK3ZJSXuf53l82e_z96Mq8fyk
range尽可能使用
代码语言:javascript复制constexpr std::string_view words{"Hello-_-C -_-20-_-!"};
constexpr std::string_view delim{"-_-"};
for (const auto word : std::views::split(words, delim)) {
std::cout << std::quoted(std::string_view(word.begin(), word.end())) << ' ';
}
或者用 https://zh.cppreference.com/w/cpp/ranges/lazy_split_view
为啥还有lazy版本?难道split_view不是lazy的?
并不是,主要原因是split_view比较难用 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2210r2.html
不展开了跑题了朋友们
Dean Moldovan - A std-fs-path from bug to patch
std::fs::path 不是unicode-safe的
特殊字母会有问题,想要用utf-8,可以用std::fs::u8path
他们不会搞定制clang-tidy规则,改系统源代码,给std::fs::path加deprecate信息。。。
Timur Doumler - C Lambda Idioms
lambda转函数指针
代码语言:javascript复制int main() {
auto f = [](int i){ return i * i; };
static_assert(std::is_same_v<decltype(f), int(*)(int)>);
}
代码语言:javascript复制注意这个加号
怎么立即执行lambda?加括号?有没有更好的写法?invoke
捕获初始化优化代码
比如这种
代码语言:javascript复制const std::vector<std::string> vs = {"apple", "orange", "foobar", "lemon"};
const std::string prefix = "foo";
auto result = std::find_if(
vs.begin(), vs.end(),
[&prefix](const std::string& s) {
return s == prefix "bar";
});
if (result != vs.end())
std::cout << prefix << "-something found!n";
这个prefix的构造就很脑瘫,怎么写更合理?把"bar"放外面?如果"bar"没法放外面只能这么构造怎么办?
代码语言:javascript复制const std::vector<std::string> vs = {"apple", "orange", "foobar", "lemon"};
const std::string prefix = "foo";
auto result = std::find_if(
vs.begin(), vs.end(),
[str = prefix "bar" ](const std::string& s) {
return s == str;
});
if (result != vs.end())
std::cout << prefix << "-something found!n";
通过捕获的构造来替换内部的构造
lambda递归调用
常规
代码语言:javascript复制int main() {
std::function<int(int)> f = [&](int i) {
if (i == 0) return 1;
return i * f(i - 1);
};
std::cout << f(5); // prints 120
}
function有类型擦除开销,有没有其他方案?Y组合子?这玩意是不是叫柯里化来着?
代码语言:javascript复制int main() {
auto f = [&](auto&& self, int i) {
if (i == 0) return 1;
return i * self(self, i - 1);
};
auto recursive = [](auto&& f, auto&&... args) {
return f(f, std::forward<decltype(args)>(args)...);
};
std::cout << recursive(f, 5); // prints 120
}
c 23的deducing this可以很好的写出来
代码语言:javascript复制int main() {
auto f = [&](this auto&& self, int i){
if (i == 0) return 1;
return i * self(i - 1);
};
std::cout << f(5); // prints 120
}
这玩意结合overload惯用法可以有更花的玩法
代码语言:javascript复制struct Leaf {};
struct Node;
using Tree = std::variant<Leaf, Node*>;
struct Node {
Tree left, right;
};
template <typename... Ts>
struct overload : Ts... { using Ts::operator()...; }
int countLeaves(const Tree& tree) {
return std::visit(overload{
[] (const Leaf&) { return 1; },
[] (this const auto& self, const Node* node) -> int {
return visit(self, node->left) visit(self, node->right);
}
},
tree);
}
其他
P99 CONF 2023 | Adventures in Thread-per-Core Async with Redpanda and Seastar by Travis Downs
https://www.bilibili.com/video/BV1gg4y1d7jB/
redpanda有一些coroutine实践,有点意思
seastar是thread per core 消息传递 share nothing,异步的处理阻塞非常重要
原来的seaster是传递future continuation的,引入couroutine就可以把then链切成co_await
但引入coroutine也是有代价的
- • 只要suspend就有栈开销,除非
- • suspend不发生,不可达 不co_await co_yeild
小的任务,不建议coroutine,能同步就同步,不能同步再then链,不能then链再coroutine
开源项目需要人手
- • asteria[4] 一个脚本语言,可嵌入,长期找人,希望胖友们帮帮忙,也可以加群384042845和作者对线
- • Unilang[5] deepin的一个通用编程语言,点子有点意思,也缺人,感兴趣的可以github讨论区或者deepin论坛看一看。这里也挂着长期推荐了
- • gcc-mcf[6] 懂的都懂
- • https://gitee.com/okstar-org/ok-edu-desktop 一个IM通信软件,做IM的可以关注,现在正在做全面整合阶段,开始组建商业团队阶段,年底开始融资,你参加了就快发财了,会的快来
引用链接
[1]
周刊项目地址: https://github.com/wanghenshui/cppweeklynews
[2]
手机qq点击进入: https://qm.qq.com/q/6NGizNPyG4
[3]
提交 issue: https://github.com/wanghenshui/cppweeklynews/issues
[4]
asteria: https://github.com/lhmouse/asteria
[5]
Unilang: https://github.com/linuxdeepin/unilang
[6]
gcc-mcf: https://gcc-mcf.lhmouse.com/