Hi, In the current architecture, the function ThisOrReplacement(m_Token) was only called in Tokenizer::GetToken()
wxString Tokenizer::GetToken()
{
m_UndoTokenIndex = m_TokenIndex;
m_UndoLineNumber = m_LineNumber;
m_UndoNestLevel = m_NestLevel;
if(m_PeekAvailable)
{
m_TokenIndex = m_PeekTokenIndex;
m_LineNumber = m_PeekLineNumber;
m_NestLevel = m_PeekNestLevel;
m_Token = m_PeekToken;
}
else
m_Token = DoGetToken();
m_PeekAvailable = false;
return ThisOrReplacement(m_Token);
}
To accelerate this "Macro replacement", I think it should be moved to DoGetToken.
Here are the reasons:
1, ThisOrReplacement(m_Token) internally use a wxString--> wxString map container, so, it will use a search algorithm in this map(normally this will cause a search on a balanced BST), this will take a lot of time.
2, we can avoid many situations to call this function, for example, when m_Token is '{' or wxEmptyString or many other string that shouldn't need macro expansion.
Any comments?
Thanks
with something like:
if(token.IsEmpty() || (token == one_constant) || (token == two_constant) || (token == three_constant))
return token;
else
return the_map.find(token);
Hi, thomas, Thanks for the full explanation about your point.
But I think you still misunderstand my mind. :(
Look at the code in DoGetToken(), I have made a pseudo code below. We can add a bool variable
bool NeedReplacement;
if (c == '_' || wxIsalpha(c))
{
..........
NeedReplacement = true;
}
else if (wxIsdigit(CurrentChar()))
{
.........
NeedReplacement = false;
}
else if (CurrentChar() == '"' || CurrentChar() == '\'')
{
......
NeedReplacement = false;
}
else if (CurrentChar() == '(')
{
......
NeedReplacement = false;
}
else
{
.......
}
if(!NeedReplacement)
return token;
else
return the_map.find(token);
Because we have already know the information of the current token, we can still save quite a lot of time. :D
Another option is to replace std::map with std::tr1::unordered_map, it if is available (gcc > 4.x.y, not sure which is the minimal x thought)
std::tr1::unordered_map is hash map, so the lookup is O(1) operation.
I personally have been using std::tr1::unordered_map for everything for ages (at least a year), I definitely think if it's available it should be used. Apparently GCC has a __GXX_EXPERIMENTAL_CXX0X__ macro. eg:
#ifdef __GXX_EXPERIMENTAL_CXX0X__
typedef std::tr1::unordered_map CBMap;
#else
typedef std::map CBMap;
#endif
CBMap<wxString, wxString> myMap;
or something like that.