我正在玩一个用于通用工业自动化的lib。为此,我需要一个通用的IO类。
IO.h
template<class T> class IOImpl {}; // pimpl idiom
template<class T> class Input;
/** IO Class
* A thread safe variable that can be reduced to a read only object
*/
template<class T>
class IO : public AbstractHMIVar
{
public:
IO( std::string name = "" );
IO( const IO<T> &io );
const T value() const;
void setValue( const T value );
Input<T> toInput() const;
IO<T> operator-=( const T &other );
IO<T> operator+=( const T &other );
IO<T> operator--();
IO<T> operator++();
const std::string stringval() const;
void fromString( const std::string val );
private:
std::shared_ptr<IOImpl<T>> pimpl_;
std::shared_ptr<std::pair<T, std::mutex>> data;
};
IO.cpp
/** Default constructor
* Create data object
*/
template<class T>
IO<T>::IO( std::string name ) : AbstractHMIVar( name ),
pimpl_( std::make_shared<IOImpl<T>>() ),
data( std::make_shared<std::pair<T, std::mutex>>() )
{
}
/** Copy constructor
* Don't allow deep copies. Only copy the shared pointer.
*/
template<class T>
IO<T>::IO( const IO<T> &io ) : pimpl_( io.pimpl_ ), data( io.data )
{
}
/** Return the value part of data pair
*/
template<class T>
const T IO<T>::value() const
{
std::lock_guard<std::mutex> lock{ data->second };
return data->first;
}
/** Return a read only version of this object
*/
template<class T>
Input<T> IO<T>::toInput() const
{
return Input<T>( *this );
}
template<class T>
IO<T> IO<T>::operator--()
{
static_assert( std::is_arithmetic<T>::value, "Type needs to be arithmetic." );
std::lock_guard<std::mutex> lock{ data->second };
data->first -= 1;
return *this;
}
template class IO<int32_t>;
问题
我编写了一个小程序来测试这个IO类的性能。
for( auto i = 0; i < n_tests; i++ )
{
IO<uint32_t> io_test( "Testvar" ); //unsigned int test
io_test.setValue( n_iterations ); //test = n_iterations
high_resolution_clock::time_point before = high_resolution_clock::now();
while( io_test.value() > 0 ) //while( test > 0 )
--io_test; //--test
results.push_back( duration_cast<milliseconds>( high_resolution_clock::now() - before ) );
}
运行80 000 000次迭代需要11.7秒。 使用不带IO类的普通uint32_t在0.0662秒内运行相同的代码。
我试图跳过共享指针,只使用没有共享指针和互斥锁定的值。但这花了很长时间。
我在编译时也尝试了不同的优化级别。没有区别。
为什么要花这么长时间?
修改
我尝试更改以下内容:
template<class T>
IO<T> IO<T>::operator--()
{
testvar -= 1;
return *this;
}
template<class T>
const T IO<T>::value() const
{
return testvar;
}
答案 0 :(得分:1)
问题在于我的操作员返回了一个IO,每次迭代都会调用复制构造函数。解决方案是:
T IO<T>::operator--();
这更像是我想要的行为。
非常感谢Paul R将我推向了剖析工具。 (之前没用过)