std::tuple的大小,这是个被错过的优化吗?

73

我已经检查了所有主要的编译器,sizeof(std::tuple<int, char, int, char>) 在它们中都是16。据推测,它们只是按顺序将元素放入元组中,因此由于对齐而浪费了一些空间。

如果元组内部存储的元素形如:int, int, char, char,那么它的 sizeof 可能为12。

这种实现方式是否可行,或者是否被标准中的某些规则禁止?


评论不适合进行长时间的讨论;此对话已被移至聊天室 - Samuel Liew
@phuclv:structtuple之间有很大的区别=>一个是语言结构,另一个是库类型。你为什么认为它们必须遵守相同的规则呢? - Matthieu M.
@MatthieuM。我在哪里说他们遵守相同的规则了? - phuclv
@phuclv:那么相关问题的意义是什么? 如果它们遵守不同的规则,查看struct的规则是没有帮助的。 - Matthieu M.
3个回答

61

std::tuple的sizeof,这是一个被忽视的优化吗?

是的。

实现是否可能做到这一点?

是的。

在[tuple]中阅读,没有对实现存储成员的模板参数顺序放置任何约束。

事实上,我能找到的每个段落似乎都尽力避免对成员声明顺序进行任何引用:get<N>()在操作语义的描述中使用。其他措辞以“元素”而不是“成员”为基础,这似乎是一个非常明确的抽象。

实际上,一些实现显然会反向存储成员, 至少可能仅是由于它们递归地使用继承来解压缩模板参数的方式(并且因为,如上所述,它们被允许这样做)。

具体来说,关于你的假设优化,我不知道是否有任何实现不存储元素在用户给定的顺序中的情况;我猜想相比于从中获得的收益,想出这样的顺序并提供std::get的机制会比较困难。如果你真的担心填充问题,当然可以仔细选择元素顺序以避免它(在某个特定平台上),就像处理类一样(而不涉及“压缩”属性的世界)。(“压缩”元组可能是一个有趣的建议……)


评论不适合进行长时间的讨论;此对话已被移至聊天室 - Samuel Liew

15
是的,这是可能的,R. Martinho Fernandes已经(大部分)完成了。他曾经有一个名为Flaming Danger Zone的博客,由于某些原因现在已经关闭,但是它的资源仍然可以在github上找到
这里是关于这个主题的Size Matters系列的全部四个部分:1234
您可能希望以原始格式查看它们,因为github不理解所使用的C++高亮标记,并将代码片段呈现为难以阅读的单行代码。
他基本上通过C++11模板元程序计算元组索引的排列,按对齐方式降序排序元素,在存储元素时根据它应用于每个访问的索引。

1
谢谢,我会查看这个的。更好的方法是按照对齐方式排序(而不是大小)。 - geza
@geza 抱歉,我错了,他确实按对齐方式排序。 - yuri kilochek
请注意,这并不意味着标准的“元组”允许以这种方式工作。因此,尽管它非常有趣,但它并没有真正回答问题。 - Lightness Races in Orbit
4
网站已经上线并且“运行”了,但是似乎被一个域名抢注者接管了,正在进行网络钓鱼攻击。他们告诉我如果我告诉他们我的谷歌密码或其他信息,就可以赢得100台平板电脑中的1台。 - Damon

-3

他们可以这样做。他们不这样做的一个可能原因是,一些架构(包括x86)具有索引模式,可以在单个指令中寻址地址base + size × index,但前提是size是2的幂。或者,如果进行对齐到16字节边界的加载或存储,则可能会稍微快一些。如果它们添加了四个填充字节,这可能会使处理std::tuple数组的代码略微更快且更紧凑。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接