从reddit/hackernews/lobsters摘抄一些c++动态
周刊项目地址|在线地址 |知乎专栏 | 腾讯云+社区 |
欢迎投稿,推荐或自荐文章/软件/资源等,请提交 issue
2022年6月25日20:28:48
标准委员会动态/ide/编译器信息放在这里
六月提案讨论 链接
编译器信息最新动态推荐关注hellogcc公众号 本周更新2022-06-22 第155期
perfbook作者的性能分析挑战赛正在进行中,有空的可以玩一下
int main() {
auto v = ranges::views::ints | ranges::views::take(2);
auto o = v | ranges::to<std::vector>();
assert(std::size(o) == 2 and o[0] == 0 and o[1] == 1);
}
标准库/boost实现的unordered map用的开链表,用的close address,
开链 == close address == table+链表模式
开放定址 == open address == table+数组内probe
优点是迭代访问比较稳定,删除也比较稳定,都是常数。为了满足常数,放弃了高效处理冲突,造成写入慢/空间占用恐怖。不可兼得啊
就是个大数组,bucket大数组,然后数组元素互相用链表串起来
最近boost 1.80 更新了新版本的unordered map,可以看他们的benchmark,性能提升显著(不要和开链法的hashmap比,那肯定被吊锤的)
在这个open address开放定址 的基础上做了性能提升,节省了内存还保持原有语义,如何做到的?
拆分metadata和普通数组, 把bucket大数组抽象成bucket组,每组N个bucket,以组为单位用链表串起来。有那种开闭链结合链表的味了。
然后每组bucket用位运算来定位
承接上文啊,为了erase count O(1)而牺牲掉insert速度真的值得吗,作者做了一个测试,对于unordered_multiset这种可重复key的,发现只要放弃这俩api的效率,insert起码上升五倍。为啥当初那么执着于erase count的效率呢
小编建议不要纠结调整api效率,选用开链的hashmap得了,absl::flat_hash_map
看个乐。以前也说过
这个答案说的方法我恰巧见过一段
https://github.com/PlatformLab/RAMCloud/blob/master/src/Cycles.h
https://github.com/PlatformLab/RAMCloud/blob/master/src/Cycles.cc
这个文章是个系列。经常更新。值得看看
c++23的特性列举一遍。没啥说的了
列举c和c++的一些区别。不要了解。了解会让你痛苦
一段神奇的代码
#include <string>
int table[4];
bool exists_in_table(int v)
{
for (int i = 0; i <= 4; i++) {
if (table[i] == v) return true;
}
return false;
}
这段代码哪里有问题?聪明的你看到了i越界了。越界应该问题不大,顶多返回个错误的值,所以越界了影响也不大,你要是这么想就错了
编译期视角,i可以越界,越界是未定义行为,未定义行为我他妈怎么搞都可以,那我认为i到不了4,提前返回了,所以这段代码直接优化成 return true
,都给编译期懂完了,暖暖的很贴心
exists_in_table(int):
mov eax, 1
ret
table:
.zero 16
再看这么一段代码
int value_or_fallback(int *p)
{
return p ? *p : 42;
}
没啥问题,如果我加一行打印呢?
int value_or_fallback(int *p)
{
printf("The value of *p is %d\n", *p);
return p ? *p : 42;
}
没有检查p就直接用,编译期一看,你这么写,我太懂你了,p一点没问题是吧,那我还检查p干嘛啊,直接return *p
,快谢谢贴心的编译器!
承接上段代码
void unwitting(bool door_is_open)
{
if (door_is_open) {
walk_on_in();
} else {
ring_bell();
// wait for the door to open using the fallback value
fallback = value_or_fallback(nullptr);
wait_for_door_to_open(fallback);
}
}
这一点问题都没有吧,调用了value_or_fallback,传个nullptr,你core就完了呗。但贴心的编译器再次出手!编译器说你居然未定义行为了!那说明else永远走不到!我太懂了!直接优化成
void unwitting(bool door_is_open)
{
walk_on_in();
}
继续,承接上段代码
void keep_checking_door()
{
for (;;) {
printf("Is the door open? ");
fflush(stdout);
char response;
if (scanf("%c", &response) != 1) return;
bool door_is_open = response == 'Y';
unwitting(door_is_open);
}
}
因为unwitting走到else会未定义行为,所以door_is_open为false会触发未定义行为,所以编译器太懂你了,door_is_open 为false我直接abort
void keep_checking_door()
{
for (;;) {
printf("Is the door open? ");
fflush(stdout);
char response;
if (scanf("%c", &response) != 1) return;
bool door_is_open = response == 'Y';
if (!door_is_open) abort();
walk_on_in();
}
}
怎么说呢。编译器,听我说,谢谢你,因为有你
写的不错
基础知识普及
了解一下gc知识
写的不错,值得复习复习。
我有点看不懂了
LTO优化二进制。能开都开(MSVC默认开)
这段代码开启LTO/IPO
# Optional IPO. Do not use IPO if it's not supported by compiler.
check_ipo_supported(RESULT result OUTPUT output)
if(result)
set_property(TARGET foo PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
else()
message(WARNING "IPO is not supported: ${output}")
endif()
有没有远程接入的工作介绍一下我要被开了