Using my new profiling stuff, I've eliminated one of the performance problems in IDA. It turned out the functions in shlwapi/path.c call CharNextA()/CharNextW() to advance characters in strings.. Although these calls are not individually that slow, the number of times they're used when opening the file dialog causes a massive delay (IDA supplies quite a large filter string to select files in the file dialogue, and iterating over the characters in this many times is what causes the problem). I've replaced the calls to CharNextA()/CharNextW() with array increments and a local static function. This knocks 3.5 seconds off the file open dialogue in IDA. BTW: I'll submit a patch with the profiling stuff tomorrow after I've finished cleaning it up.
Index: dlls/shlwapi/path.c =================================================================== RCS file: /home/wine/wine/dlls/shlwapi/path.c,v retrieving revision 1.38 diff -u -r1.38 path.c --- dlls/shlwapi/path.c 22 Sep 2003 19:46:32 -0000 1.38 +++ dlls/shlwapi/path.c 29 Nov 2003 23:17:19 -0000 @@ -57,6 +57,19 @@ HRESULT WINAPI SHGetWebFolderFilePathW(LPCWSTR,LPWSTR,DWORD); +static LPSTR _charNextA( LPCSTR ptr ) +{ + static const union cptable *ansi_cptable = NULL; + if (!ansi_cptable) { + ansi_cptable = wine_cp_get_table( 1252 ); + } + + if (!*ptr) return (LPSTR)ptr; + if (is_dbcs_leadbyte(ansi_cptable, ptr[0]) && ptr[1]) return (LPSTR)(ptr + 2); + return (LPSTR)(ptr + 1); +} + + /************************************************************************* * PathAppendA [SHLWAPI.@] * @@ -332,7 +345,7 @@ if ((*lpszPath == '\\' || *lpszPath == '/' || *lpszPath == ':') && lpszPath[1] && lpszPath[1] != '\\' && lpszPath[1] != '/') lastSlash = lpszPath + 1; - lpszPath = CharNextA(lpszPath); + lpszPath = _charNextA(lpszPath); } return (LPSTR)lastSlash; } @@ -353,7 +366,7 @@ if ((*lpszPath == '\\' || *lpszPath == '/' || *lpszPath == ':') && lpszPath[1] && lpszPath[1] != '\\' && lpszPath[1] != '/') lastSlash = lpszPath + 1; - lpszPath = CharNextW(lpszPath); + lpszPath++; } return (LPWSTR)lastSlash; } @@ -384,7 +397,7 @@ lastpoint = NULL; else if (*lpszPath == '.') lastpoint = lpszPath; - lpszPath = CharNextA(lpszPath); + lpszPath = _charNextA(lpszPath); } } return (LPSTR)(lastpoint ? lastpoint : lpszPath); @@ -409,7 +422,7 @@ lastpoint = NULL; else if (*lpszPath == '.') lastpoint = lpszPath; - lpszPath = CharNextW(lpszPath); + lpszPath++; } } return (LPWSTR)(lastpoint ? lastpoint : lpszPath); @@ -443,7 +456,7 @@ return (LPSTR)lpszPath + 1; if (*lpszPath == '"') bSeenQuote = !bSeenQuote; - lpszPath = CharNextA(lpszPath); + lpszPath = _charNextA(lpszPath); } } return (LPSTR)lpszPath; @@ -468,7 +481,7 @@ return (LPWSTR)lpszPath + 1; if (*lpszPath == '"') bSeenQuote = !bSeenQuote; - lpszPath = CharNextW(lpszPath); + lpszPath++; } } return (LPWSTR)lpszPath; @@ -548,7 +561,7 @@ if (*lpszPath == '\\') lpszFileSpec++; } - if (!(lpszPath = CharNextA(lpszPath))) + if (!(lpszPath = _charNextA(lpszPath))) break; } @@ -591,8 +604,7 @@ if (*lpszPath == '\\') lpszFileSpec++; } - if (!(lpszPath = CharNextW(lpszPath))) - break; + if (*lpszPath) lpszPath++; } if (*lpszFileSpec) @@ -840,7 +852,7 @@ LPSTR start = lpszPath; while (*lpszPath == ' ') - lpszPath = CharNextA(lpszPath); + lpszPath = _charNextA(lpszPath); while(*lpszPath) *start++ = *lpszPath++; @@ -1547,7 +1559,7 @@ return FALSE; bSeenSlash = TRUE; } - lpszPath = CharNextA(lpszPath); + lpszPath = _charNextA(lpszPath); } return TRUE; } @@ -1587,7 +1599,7 @@ return FALSE; bSeenSlash = TRUE; } - lpszPath = CharNextW(lpszPath); + lpszPath++; } return TRUE; } @@ -1733,8 +1745,8 @@ if (toupper(*mask) != toupper(*name) && *mask != '?') return FALSE; - name = CharNextA(name); - mask = CharNextA(mask); + name = _charNextA(name); + mask = _charNextA(mask); } if (!*name) @@ -1767,8 +1779,8 @@ if (toupperW(*mask) != toupperW(*name) && *mask != '?') return FALSE; - name = CharNextW(name); - mask = CharNextW(mask); + if (*name) name++; + if (*mask) mask++; } if (!*name) { @@ -1811,7 +1823,7 @@ return TRUE; /* Matches the current mask */ while (*lpszMask && *lpszMask != ';') - lpszMask = CharNextA(lpszMask); + lpszMask = _charNextA(lpszMask); if (*lpszMask == ';') { @@ -1988,7 +2000,7 @@ { if (*lpszPath == '\\' || *lpszPath == ':') return FALSE; - lpszPath = CharNextA(lpszPath); + lpszPath = _charNextA(lpszPath); } return TRUE; } @@ -2009,7 +2021,7 @@ { if (*lpszPath == '\\' || *lpszPath == ':') return FALSE; - lpszPath = CharNextW(lpszPath); + lpszPath++; } return TRUE; } @@ -2158,7 +2170,7 @@ { if (*lpszPath == '\\') return FALSE; - lpszPath = CharNextA(lpszPath); + lpszPath = _charNextA(lpszPath); } return TRUE; } @@ -2180,7 +2192,7 @@ { if (*lpszPath == '\\') return FALSE; - lpszPath = CharNextW(lpszPath); + lpszPath++; } return TRUE; } @@ -2219,7 +2231,7 @@ return FALSE; bSeenSlash = TRUE; } - lpszPath = CharNextA(lpszPath); + lpszPath = _charNextA(lpszPath); } return bSeenSlash; } @@ -2246,7 +2258,7 @@ return FALSE; bSeenSlash = TRUE; } - lpszPath = CharNextW(lpszPath); + lpszPath++; } return bSeenSlash; }