字符串引用参数的效率C++
Efficiency of string reference parameters in C++
C++当参数是字符串时,通过使它们引用字符串对象,就像当参数是程序员创建的类的对象一样时,是否有任何明显的速度/效率?例如,如果我有一个名为 Person 的类,它有名字和姓氏,我可以为其中一个构造函数做:
Person(const string& firstName, const string& lastName);
与。
Person(string firstName, string lastName);
是第一个更有效率,还是获得的效率微不足道以至于无关紧要?
是第一个更有效率的,
它可能是,潜在的。但不一定。
还是获得的效率微不足道,无关紧要?
这取决于很多事情。如果字符串很短(足以适应目标系统的小字符串优化(,那么无论哪种方式,差异都可能很小。
如果您不打算存储字符串的副本,并且字符串很大,则引用可能会明显更快。
如果要存储副本,并将右值传递给函数,并且字符串很大,则非引用可能会明显更快,因为您可以通过移动来创建副本。
无论如何,这些替代方案之间的差异在您的程序中是否显着,只能通过测量来找到。
而不是这两种方法
Person(const string& firstName, const string& lastName);
和
Person(string firstName, string lastName);
更有效的方法是将以下两个构造函数放在一起时
Person(const string &firstName, const string &lastName);
Person( string &&firstName, string &&lastName );
这种方法
Person(const string& firstName, const string& lastName);
当参数为右值时效率较低。
这种方法
Person(string firstName, string lastName);
当参数为左值时效率较低。
以下是两个演示程序,显示了三种方法之间的差异。
#include <iostream>
struct A
{
static int value;
explicit A() : x( ++value )
{
std::cout << "explicit A(), x = " << x << "n";
}
A( const A &a ) noexcept : x( ++value )
{
std::cout << "A( const A & ), x = " << x << "n";
}
A( A &&a ) noexcept : x( ++value )
{
std::cout << "A( A && ), x = " << x << "n";
}
~A()
{
std::cout << "~A(), x = " << x << "n";
}
int x;
};
int A::value = 0;
struct B
{
B( const A &a1, const A &a2 ) : a1( a1 ), a2( a2 )
{
std::cout << "B( const A &, const A & )n";
}
A a1, a2;
};
struct C
{
C( A a1, A a2 ) : a1( std::move( a1 ) ), a2( std::move( a2 ) )
{
std::cout << "C( A, A )n";
}
A a1, a2;
};
struct D
{
D( const A &a1, const A &a2 ) : a1( a1 ), a2( a2 )
{
std::cout << "D( const A &, const A & )n";
}
D( A &&a1, A &&a2 ) : a1( std::move( a1 ) ), a2( std::move( a2 ) )
{
std::cout << "D( A &&, A && )n";
}
A a1, a2;
};
int main()
{
A a1;
A a2;
std::cout << 'n';
B b( a1, a2 );
std::cout << "b.a1.x = " << b.a1.x << ", b.a2.x = " << b.a2.x << 'n';
std::cout << 'n';
C c( a1, a2 );
std::cout << "c.a1.x = " << c.a1.x << ", c.a2.x = " << c.a2.x << 'n';
std::cout << 'n';
D d( a1, a2 );
std::cout << "d.a1.x = " << d.a1.x << ", d.a2.x = " << d.a2.x << 'n';
std::cout << 'n';
return 0;
}
程序输出为
explicit A(), x = 1
explicit A(), x = 2
A( const A & ), x = 3
A( const A & ), x = 4
B( const A &, const A & )
b.a1.x = 3, b.a2.x = 4
A( const A & ), x = 5
A( const A & ), x = 6
A( A && ), x = 7
A( A && ), x = 8
C( A, A )
~A(), x = 6
~A(), x = 5
c.a1.x = 7, c.a2.x = 8
A( const A & ), x = 9
A( const A & ), x = 10
D( const A &, const A & )
d.a1.x = 9, d.a2.x = 10
~A(), x = 10
~A(), x = 9
~A(), x = 8
~A(), x = 7
~A(), x = 4
~A(), x = 3
~A(), x = 2
~A(), x = 1
和
#include <iostream>
struct A
{
static int value;
explicit A() : x( ++value )
{
std::cout << "explicit A(), x = " << x << "n";
}
A( const A &a ) noexcept : x( ++value )
{
std::cout << "A( const A & ), x = " << x << "n";
}
A( A &&a ) noexcept : x( ++value )
{
std::cout << "A( A && ), x = " << x << "n";
}
~A()
{
std::cout << "~A(), x = " << x << "n";
}
int x;
};
int A::value = 0;
struct B
{
B( const A &a1, const A &a2 ) : a1( a1 ), a2( a2 )
{
std::cout << "B( const A &, const A & )n";
}
A a1, a2;
};
struct C
{
C( A a1, A a2 ) : a1( std::move( a1 ) ), a2( std::move( a2 ) )
{
std::cout << "C( A, A )n";
}
A a1, a2;
};
struct D
{
D( const A &a1, const A &a2 ) : a1( a1 ), a2( a2 )
{
std::cout << "D( const A &, const A & )n";
}
D( A &&a1, A &&a2 ) : a1( std::move( a1 ) ), a2( std::move( a2 ) )
{
std::cout << "D( A &&, A && )n";
}
A a1, a2;
};
int main()
{
B b( A{}, A{} );
std::cout << "b.a1.x = " << b.a1.x << ", b.a2.x = " << b.a2.x << 'n';
std::cout << 'n';
C c( A{}, A{} );
std::cout << "c.a1.x = " << c.a1.x << ", c.a2.x = " << c.a2.x << 'n';
std::cout << 'n';
D d( A{}, A{} );
std::cout << "d.a1.x = " << d.a1.x << ", d.a2.x = " << d.a2.x << 'n';
std::cout << 'n';
return 0;
}
程序输出为
explicit A(), x = 1
explicit A(), x = 2
A( const A & ), x = 3
A( const A & ), x = 4
B( const A &, const A & )
~A(), x = 2
~A(), x = 1
b.a1.x = 3, b.a2.x = 4
explicit A(), x = 5
explicit A(), x = 6
A( A && ), x = 7
A( A && ), x = 8
C( A, A )
~A(), x = 6
~A(), x = 5
c.a1.x = 7, c.a2.x = 8
explicit A(), x = 9
explicit A(), x = 10
A( A && ), x = 11
A( A && ), x = 12
D( A &&, A && )
~A(), x = 10
~A(), x = 9
d.a1.x = 11, d.a2.x = 12
~A(), x = 12
~A(), x = 11
~A(), x = 8
~A(), x = 7
~A(), x = 4
~A(), x = 3
可以看出,在这两个程序中,与类B
和C
相比,类D
的行为更有效。
嗯, 你让我想起了我的一位教授曾经教过我的一条好的经验法则。
当您必须决定是否将对象传递给函数时 按值或按引用:如果对象大于对它的引用,最多 4 倍- 我们将传递对象本身, 如果它大于 4x- 那么我们将传递对它的引用。
当然,这是基于这样的假设,即无论哪种方式,我们都不打算更改对象。
相关文章:
- 为什么当我解模块化时,这个C++代代码"效率较低"?
- 代码的效率. 转到和函数调用
- 对于循环C++可能效率低下
- 内存效率表示最短路径的方法?
- 如何提高该函数的运行效率?
- 效率:标准::数组与标准::矢量
- 如何提高BST的搜索操作效率?
- 字符串引用参数的效率C++
- 提高基于组件的游戏引擎的效率
- 在 c++ 中使用带有映射的插入效率
- 关于效率的问题
- 在SQLITE数据库中写入记录需要花费大量时间.如何提高刀片操作效率?
- 寻求提高Microsoft密封库计算效率的方法
- 做对了一个类似竞争的问题,但需要帮助来提高效率
- C++ - 与 Numpy 中的矢量版本相比,Argsort 效率低的矢量版本实现
- C++,在对象内分配多个数据时,堆栈分配是否更有效? 在下面的程序中,类A_Heap的效率会更低吗?
- visual C++|循环效率
- 我创建了一个库,想知道设计是否效率低下
- 矩阵rowSums()与colSums(()在R与Rcpp与Armadillo中的效率
- 共享指针的复制和交换效率