BUG: _MBCS String Functions of the MSVCRT.DLL file (version 6.1.8637.0) Is Slower than Earlier Versions (264795)



The information in this article applies to:

  • Microsoft Windows 2000 Server
  • Microsoft Windows 2000 Advanced Server
  • Microsoft Windows 2000 Professional

This article was previously published under Q264795

SYMPTOMS

Multibyte character set (MBCS) string functions, such as _ismbcspace, that are provided by the Msvcrt.dll file (version 6.1.8637.0) released with both Microsoft Windows 2000 and Microsoft Windows ME have a slower performance than earlier versions of the Msvcrt.dll file released with Microsoft Windows NT 4.0, Windows 9x, or Visual C++ 6.0. The slower performance affects any application that directly or indirectly uses the MBCS string functions of the Msvcrt.dll file.

The Mfc42.dll file is built with a _MBCS processor directive by default, and the Microsoft Foundation Class Library (MFC) CString functions use the Msvcrt.dll file MBCS functions by default. Applications that use MFC CString functions have a slower performance when they run on Windows 2000 and Windows ME than when they run on Windows 9x and Windows NT 4.0.

The degree of performance degradation depends on how intensive the application uses the run-time MBCS string functions or MFC CString functions.

RESOLUTION

To resolve this problem, obtain the latest service pack for Windows 2000. For additional information, click the following article number to view the article in the Microsoft Knowledge Base:

260910 How to Obtain the Latest Windows 2000 Service Pack

The following are three possible work arounds to resolve the problem:
  1. Rebuild the application to statically link to the run-time library. The static library does not have the performance delay with MBCS string functions on Windows 2000 and Windows ME.
  2. Modify the application to be Unicode compatible on Windows 2000. For example, use _ttoi(argv[1]) in the sample code located in the "More Information" section of this article instead of atoi(argv[1]). Rebuild the application with the _UNICODE manifest instead of _MBCS. If the application uses the MFC, the Unicode version of the MFC library is used by default. Refer to the MSDN library for more information about Unicode programming.
  3. If your application only uses single-byte character set (SBCS), rebuild the application without the _MBCS manifest. If the application uses the MFC CString functions, you will still encounter this MBCS problem because MFC is built with _MBCS by default. The following are two possible work arounds for this case:
    • Add \MFC\SRC\Strex.cpp to your project, and then compile it without _MBCS. The Strex.cpp file implements the CString functions. This may not work if your application uses the MFC library indirectly when other DLL's that are used by your application use MFC CString functions.
    • Rebuild the MFC library with MBCS=0. Add the MFC42.LIB file to the "Ignore Libraries" project setting, and then link your custom MFC library with your application. Refer to technician note TN033 for "Rebuilding the MFC DLL" procedures.

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article. This problem was first corrected in Windows 2000 Service Pack 2.

MORE INFORMATION

Steps to Reproduce the Behavior

  • Create a Win32 Console Application project with the following code:
    #include <windows.h>
    #include <tchar.h>
    #include <process.h>
    #include <stdio.h>
    
    unsigned int __stdcall threadfunc(void *)
    {
        for (int v = 0; v <= 10000000; ++v)
    	_istspace(' ');
    	return 0;
    }
    
    int main(int argc, char **argv)
    {
        if (argc != 2)
    	{
    		printf("Usage: <appname.exe> <# of threads>\n");
    		exit(1);
    	}
    
        int nthreads = atoi(argv[1]);
        //int nthreads = _ttoi(argv[1]);  //UNICODE version
    
        HANDLE *handles = new HANDLE[nthreads];
    	unsigned int *threadID = new unsigned int[nthreads];
    
        for (int i = 0; i < nthreads; ++i) {
    	handles[i] = (HANDLE) _beginthreadex(NULL, 0, &threadfunc, NULL, 0, &threadID[i]);
        }
    
        WaitForMultipleObjects(nthreads, handles, TRUE, INFINITE);
    
    	delete [] handles;
    	delete [] threadID;
    
        return 0;
    }
    						

  • Build the application using the Multithreaded DLL run-time library Msvcrt.dll file. The project is built with the _MBCS processor directive by default and _istspace() is mapped to _ismbcspace(). This application runs slower on Windows 2000 and Windows ME than on Windows NT 4.0 and Windows 9x.

REFERENCES

"Strings: Overview," "Multibyte Character Sets (MBCS): Overview," and "Unicode Programming: Overview" in MSDN under Visual C++ Documentation / Visual C++ Programmer's Guide /Adding Program Functionality /Overviews.

TN033: DLL Version of MFC


Modification Type:MinorLast Reviewed:9/26/2005
Keywords:kbHotfixServer kbQFE kbBug kbCRT kbfix KB264795