我有一个函数,我无限次地调用(或直到满足条件)。这种递归函数的问题在于,在更高级别上,它由工作线程调用,该工作线程推送并弹出一个双端队列。与此同时,我正在使用主线程迭代文件,这比递归函数快得多,递归函数处理从迭代通过主循环检索的数据。下面是严重减慢速度的代码示例如下:
bool CCapsule::DecodeElementList( ElementList &elementList, char* pszBuffer, unsigned int uiBufferLength, std::string strSrcAddress, std::string strDestAddress, std::vector<std::string> &vsContents, bool bIsInner )
{
// Create an buffer to contain pszBuffer.
RBuffer rBuffer;
rBuffer.data = pszBuffer;
// Create an RElement List and Element Entry to store elements
RRet rRet;
RElementEntry rElementEntry;
// Decode Element List
if(rDecodeElementList(&m_rDecodeIter, &rElementList, 0) >= RET_SUCCESS)
{
std::vector<std::string> _vsContents;
while ((RRet = rDecodeElementEntry(&m_rDecodeIter, &rElementEntry)) != RRET_END_OF_CONTAINER)
{
if (RRet < RET_SUCCESS)
{
return false;
}
std::string strEntryName = "";
if (rElementEntry.data != NULL)
rElementEntry.data;
switch(rElementEntry.dataType)
{
case R_MSG:
// Create a new RCapsule to encapsulate the inner message.
m_pInnerMessage = new CCapsule();
if ( false == m_pInnerMessage->Load( pszBuffer, uiBufferLength, strSrcAddress, strDestAddress, _vsContents, true ) )
{
// An error occurred, clean up.
delete m_pInnerMessage;
m_pInnerMessage = 0;
return false;
}
break;
case R_ELEMENT_LIST:
// Decode Element List
RElementList rInnerElementList;
DecodeElementList(rInnerElementList, pszBuffer, uiBufferLength, strSrcAddress, strDestAddress, _vsContents, true);
break;
case R_FIELD_LIST:
// Decode Field List
DecodeFieldList(pszBuffer, uiBufferLength);
break;
case R_DATE:
{
// Decode DATE
RDate rDate;
RRet = rDecodeDate( &m_rDecodeIter, &rDate );
if ( RRet != RET_SUCCESS )
{
return false;
}
std::stringstream sstream;
sstream << static_cast<int>( rDate.day ) << "/" << static_cast<int>( rDate.month ) << "/" << rDate.year;
_vsContents.push_back(sstream.str());
}
break;
case R_DATETIME:
{
// Decode DATETIME
RDateTime rDateTime;
RRet = rDecodeDateTime( &m_rDecodeIter, &rDateTime );
if ( RRet != RET_SUCCESS )
{
return false;
}
RBuffer rStringBuffer;
RRet = rDateTimeToString( &rStringBuffer, R_DATETIME, &rDateTime );
if ( RRet != RET_SUCCESS )
{
return false;
}
std::stringstream sstream;
sstream << static_cast<int>( rDateTime.date.day ) << "/" << static_cast<int>( rDateTime.date.month ) << "/" << static_cast<int>( rDateTime.date.year) << " " << static_cast<int>( rDateTime.time.hour )
<< ":" << static_cast<int>( rDateTime.time.minute ) << ":" << static_cast<int>( rDateTime.time.second ) << "." << static_cast<int>( rDateTime.time.millisecond );
_vsContents.push_back(sstream.str());
}
break;
case R_DOUBLE:
// Decode DOUBLE
RDouble rDouble;
RRet = rDecodeDouble( &m_rDecodeIter, &rDouble );
_vsContents.push_back(boost::lexical_cast<std::string>(rDouble));
//m_sStringStream << rDouble << ",";
break;
case R_UINT:
// Decode UINT
RUInt rUInt;
RRet = rDecodeUInt( &m_rDecodeIter, &rUInt );
_vsContents.push_back(boost::lexical_cast<std::string>(rUInt));
//m_sStringStream << rUInt << ",";
break;
case R_ASCII_STRING:
{
// Decode STRING
RBuffer rStringBuffer;
RRet = rDecodeBuffer( &m_rDecodeIter, &rStringBuffer );
std::string strData(rStringBuffer.data);
_vsContents.push_back(strData);
//m_sStringStream << rStringBuffer.data << ",";
}
break;
case R_NO_DATA:
RRet = RET_SUCCESS;
break;
default:
RRet = RET_FAILURE;
break;
}
}
std::stringstream ssReport;
std::copy(_vsContents.cbegin(),_vsContents.cend(),std::ostream_iterator<std::string>(ssReport,","));
vsContents.push_back(ssReport.str());
}
else
{
return false;
}
return true;
}
不幸的是,它必须按照这个顺序排列,因为存储的字符串向量将包含逗号分隔元素的列表,我将稍后输出到csv列表。这段代码只是解码某些元素并将结果字符串推回到字符串向量中,然后将其放入字符串流中。
有没有人对如何提高性能有任何建议?感谢...
答案 0 :(得分:3)
递归本身对性能没有影响。您的性能问题将更为传统,例如:
if (rElementEntry.data != NULL) rElementEntry.data;
等荒谬的陈述不会做任何有用的事情,但它们可能会花费你的CPU周期。答案 1 :(得分:1)
通过将通常传递给递归函数的参数推送到堆栈,您可以尝试通过迭代算法替换递归算法。
喜欢的东西:
Stack<Object> stack = new Stack<Object>;
stack.push(first_object);
while( !stack.isEmpty() ) {
// Do something
my_object = stack.pop();
// Push other objects on the stack.
}
这种技术称为递归消除。 检查此链接。
http://cs.saddleback.edu/rwatkins/CS2B/Lab%20Exercises/Stacks%20and%20Recursion%20Lab.pdf
答案 2 :(得分:0)
我觉得你的代码中有两件事是重要的:
Access()
方法,并使代码更清晰。snprintf
作为@Kylotan建议。以上更改可以使您的代码比以前更快。如果它仍然无法满足您的标准,那么您需要尝试一些分析工具。