野牛价值移动/效率
Bison value moving / efficiency
我正在努力从野牛的语义值构建我的解析数据结构。一种特定的结构是 std::vector<double>
型。我很好奇野牛内部如何处理移动的语义值。我尝试分析c ++ .m4文件,发现:
template <typename Base>
inline
void
]b4_parser_class_name[::basic_symbol<Base>::move (basic_symbol& s)
{
super_type::move(s);
]b4_variant_if([b4_symbol_variant([this->type_get ()], [value], [move],
[s.value])],
[value = s.value;])[]b4_locations_if([
location = s.location;])[
}
不幸的是,我无法破译这一点,以找出移动像 std::vector 这样的数据结构的效率,部分原因是我对 m4 语法的无知。
在我的语法中给出这个:
%define api.token.constructor
%define api.value.type variant
%type < std::vector<double> > numlist
...
numlist:
num { $$ = std::vector<double>(); $$.push_back($1); }
| numlist "," num { $$ = $1; $$.push_back($3); }
;
我不确定性能影响。请注意,这将使用 C++98 编译器而不是 C++11 编译器进行编译;因此不会有移动语义。
我猜$$ = std::vector<double>()
语句可以删除;我认为它已经是默认构造的,但我还没有测试过,我不确定野牛的内部变体类型是如何工作的。我特别感兴趣的是$$ = $1; $$.push_back($3);
是否会为要添加的每个项目复制矢量?
我不能确定这是否是将类型切换到std::vector<double> *
的情况;诚然,使用野牛的变体类型背后的大部分原因是使用纯C++类型而不是指针的联合。
我对解析器也有类似的好奇心,它实际上确实使用了 C++11/14,尤其是std::unique_ptr
.如果分配了左递归规则的一行,比如$$ = std::make_unique<...>(...)
,下面能做$$ = $1; $$->...
吗?
我不是Bison/Yacc专家,但您可以查看生成的代码:
{
case 2:
#line 20 "test.yy" // lalr1.cc:846
{ yylhs.value.as< std::vector<double> > () = std::vector<double>();
yylhs.value.as< std::vector<double> > ().push_back(yystack_[0].value.as< double > ()); }
#line 1306 "test.tab.cc" // lalr1.cc:846
break;
case 3:
#line 21 "test.yy" // lalr1.cc:846
{ yylhs.value.as< std::vector<double> > () = yystack_[2].value.as< std::vector<double> > ();
yylhs.value.as< std::vector<double> > ().push_back(yystack_[0].value.as< double > ()); }
#line 1312 "test.tab.cc" // lalr1.cc:846
break;
它位于 parser::parse
方法内部,其中 yylhs
是 stack_symbol_type
类型的局部变量,yystack_
是类型 stack_type
的 parser
类的属性(包含 stack_symbol_type
)。
看起来答案是肯定的,当你做$$ = $1
时,整个向量将被复制,而且我不明白编译器如何优化这一点。as
声明如下:
template <typename T>
T& as();
使用const
变体,因此影响是在类型 T
上完成的,在您的情况下是std::vector<double>
,因此会制作副本。即使您使用 c++11 移动语义,也会制作副本,因为 RHS 不是xvalue
。
- 将对象移动到std::shared_ptr
- 何时在引用或唯一指针上使用移动语义
- 如何从具有移动语义的类对象中生成共享指针
- 将shared_ptr移动到<StructA>shared_ptr<变体<结构A、结构 B>>
- C / C++ 移位/偏移/向左或向右移动位图?
- MSVC将仅移动结构参数解释为指针
- 自定义先决条件对移动分配运算符有效吗
- 返回值优化:显式移动还是隐式
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 为什么复制而不是移动数据元素?
- 可以使用移动语义更改或改进此C++代码吗?
- 使lambda不可复制/不可移动
- c++在使用指针时移动语义
- 为什么当我解模块化时,这个C++代代码"效率较低"?
- 将QGraphicsItem的移动区域限制在多边形区域内
- 复制和移动构造函数之间的效率差异
- 为什么同时使用一个赋值运算符处理复制和移动赋值效率不高
- 为什么移动返回到函数末尾的效率较低
- 野牛价值移动/效率
- 首先创建字符串,然后通过移动语义将其添加到 vector 或在 vector 中创建元素是否具有内存效率