XML Designer


Licence agreement


Copyright


Downloads Products & Services Support Clients Open Source About



Home / Downloads / XML Designer / Compare parsers

The follow table compares different popular XML parsers supporting XML 1.0 specification.

Company/Parserxml file sizeparsing timeparsing speedallocated memorymultiplication memorycomments
Recreate object
Terimber/Xml Designer 1.710Kb1.2 msec8.3Mb/sec1Mb-Internal buffer allocated
Microsoft/MSXML4.010Kb2.4 msec4.2 Mb/sec124 b-Internal buffer already was allocated
Oracle/XML Parser 9.2.0.4.0 C++10Kb1.9 msec5.3 Mb/sec42 Kb4.2
Apache/Xerces-C++ Version 2.3.010Kb2.6 msec3.8 Mb/sec2.8 Mb-Internal buffer allocated
Reuse object
Terimber/Xml Designer 1.710Kb0.95 msec10.5 Mb/sec124bReusing internal buffer
Microsoft/MSXML4.010Kb2.5 msec4 Mb/sec66 bReusing internal buffer
Oracle/XML Parser 9.2.0.4.0 C++10Kb1 msec10 Mb/sec7 KbReusing internal buffer
Apache/Xerces-C++ Version 2.3.010Kb----Doesn't support reusing object
Recreate object
Terimber/Xml Designer 1.7100Kb9 msec11Mb/sec1.2 Mb-Internal buffer allocated
Microsoft/MSXML4.0100Kb15 msec6.7 Mb/sec325 Kb3.25Internal buffer allocated
Oracle/XML Parser 9.2.0.4.0 C++100Kb11 msec9.1 Mb/sec242 Kb2.4
Apache/Xerces-C++ Version 2.3.0100Kb25 msec4 Mb/sec3 Mb-Internal buffer allocated
Reuse object
Terimber/Xml Designer 1.7100Kb9 msec10.5 Mb/sec1.4 KbReusing internal buffer
Microsoft/MSXML4.0100Kb17 msec4 Mb/sec708 bReusing internal buffer
Oracle/XML Parser 9.2.0.4.0 C++100Kb9 msec10 Mb/sec94 KbReusing internal buffer
Apache/Xerces-C++ Version 2.3.0100Kb----Doesn't support reusing object
Recreate object
Terimber/Xml Designer 1.71Mb88 msec11.4 Mb/sec3.8 Mb3.8
Microsoft/MSXML4.01Mb146 msec6.7 Mb/sec6.8 Mb6.7
Oracle/XML Parser 9.2.0.4.0 C++1Mb106 msec9.4 Mb/sec14.9 Mb14.9
Apache/Xerces-C++ Version 2.3.01Mb260 msec3.8 Mb/sec11 Mb11
Reuse object
Terimber/Xml Designer 1.71Mb89 msec11.2 Mb/sec66 Kb-Reusing internal buffer
Microsoft/MSXML4.01Mb175 msec5.7 Mb/sec708 b-Reusing internal buffer
Oracle/XML Parser 9.2.0.4.0 C++1Mb91 msec11 Mb/sec1.2 Mb-Reusing internal buffer
Apache/Xerces-C++ Version 2.3.01Mb----Doesn't support reusing object
Recreate object
Terimber/Xml Designer 1.710Mb846 msec11.8 Mb/sec32.7 Mb3.3
Microsoft/MSXML4.010Mb1.66 sec6.2 Mb/sec63.4 Mb6.3
Oracle/XML Parser 9.2.0.4.0 C++10Mb1.0 sec10 Mb/sec29.5 Mb2.9
Apache/Xerces-C++ Version 2.3.010Mb2.5 sec4 Mb/sec89 Mb8.9
Reuse object
Terimber/Xml Designer 1.710Mb857 msec11.7 Mb/sec3.3 Mb-Reusing internal buffer
Microsoft/MSXML4.010Mb1.93 sec5.2 Mb/sec64 Mb6.4
Oracle/XML Parser 9.2.0.4.0 C++10Mb891 msec11.2 Mb/sec29.5 Mb2.95
Apache/Xerces-C++ Version 2.3.010Mb----Doesn't support reusing object
Recreate object
Terimber/Xml Designer 1.7100Mb8.45 sec11.8 Mb/sec317 Mb3.2
Microsoft/MSXML4.0100Mb42.88 sec2.3 Mb/sec645 Mb6.5
Oracle/XML Parser 9.2.0.4.0 C++100Mb-->1.2 Gb-No enough memory
Apache/Xerces-C++ Version 2.3.0100Mb-->900 Mb-No enough memory
Reuse object
Terimber/Xml Designer 1.7100Mb8.63 sec11.7 Mb/sec317 Mb3.2
Microsoft/MSXML4.0100Mb43.06 sec2.3 Mb/sec646 Mb6.5
Oracle/XML Parser 9.2.0.4.0 C++100Mb-->1.2 Gb-No enough memory
Apache/Xerces-C++ Version 2.3.0100Mb----Doesn't support reusing object


For recreation of object the follow test code was used:

		PROCESS_MEMORY_COUNTERS p;
		p.cb= sizeof(PROCESS_MEMORY_COUNTERS);
		HANDLE h = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ::GetCurrentProcessId());
	
		//Cstring path = "C:\xmltest\build1.xml";	
		//Cstring path = "C:\xmltest\build10.xml";	
		//Cstring path = "C:\xmltest\build100.xml";	
		//Cstring path = "C:\xmltest\build1000.xml";	
		//Cstring path = "C:\xmltest\build10000.xml";	

		//__int64 rounds = 1; - 100Mb file
		//__int64 rounds = 10; - 10Mb file
		//__int64 rounds = 100; - 1Mb file
		//__int64 rounds = 1000; - 100Kb file
		//__int64 rounds = 10000; - 10 Kb file

		__int64 memory_ = 0;
		__int64 time_ = 0;
		LARGE_INTEGER ticks;
		QueryPerformanceFrequency(&ticks);

		VARIANT_BOOL resVar;
		VARIANT vpath;
		vpath.bstrVal = path.AllocSysString();
		vpath.vt = VT_BSTR;

		/*
		//////////////// terimber

		const CLSID clsidt = {0xE9F698B3, 0xB48E, 0x4977, {0xA7, 0x73, 0x48, 0x95, 0xB8, 0x1C, 0x3D, 0x90}};
		const IID iidt = {0x3C11D17E, 0x5A2C, 0x446E, {0x9E, 0x9B, 0xF1, 0x28, 0x15, 0xC9, 0xD8, 0xB8}}; // IID_IXmlDesigner

		for (__int64 rind = 0; rind < rounds; ++rind)
		{
			LARGE_INTEGER tbefore, tafter;
			::GetProcessMemoryInfo(h, &p, p.cb);
			__int64 mbefore = p.WorkingSetSize + p.PagefileUsage;
			IXmlDesigner* p_IXmlDesigner = 0;
			HRESULT hr = ::CoCreateInstance(clsidt, 0, CLSCTX_INPROC_SERVER, iidt, (void**)&p_IXmlDesigner);

			QueryPerformanceCounter(&tbefore);
			hr = p_IXmlDesigner->load(vpath.bstrVal, 0, &resVar);
			QueryPerformanceCounter(&tafter);
			::GetProcessMemoryInfo(h, &p, p.cb);
			__int64 mafter = p.WorkingSetSize + p.PagefileUsage;
				
			p_IXmlDesigner->Release();
			memory_ += (mafter - mbefore);
			time_ += (tafter.QuadPart - tbefore.QuadPart) * 1000000 / ticks.QuadPart;
		}

		*/

		// microsoft
		/*
		const CLSID clsid = {0x88d969c0, 0xf192, 0x11d4, {0xa6, 0x5f, 0x00, 0x40, 0x96, 0x32, 0x51, 0xe5 }};
		const IID iid = {0x2933BF95, 0x7B36, 0x11d2, {0xB2,0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60}}; // IID_IXMLDOMDocument2


		for (__int64 rind = 0; rind < rounds; ++rind)
		{
			LARGE_INTEGER tbefore, tafter;
			::GetProcessMemoryInfo(h, &p, p.cb);
			__int64 mbefore = p.WorkingSetSize + p.PagefileUsage;
			IXMLDOMDocument2* p_IXMLDOMDocument2 = 0;
			HRESULT hr = ::CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, iid, (void**)&p_IXMLDOMDocument2);

			QueryPerformanceCounter(&tbefore);
			hr = p_IXMLDOMDocument2->load(vpath, &resVar);
			QueryPerformanceCounter(&tafter);
			::GetProcessMemoryInfo(h, &p, p.cb);
			__int64 mafter = p.WorkingSetSize + p.PagefileUsage;
				
			p_IXMLDOMDocument2->Release();
			memory_ += (mafter - mbefore);
			time_ += (tafter.QuadPart - tbefore.QuadPart) * 1000000 / ticks.QuadPart;
		}

		*/

		// oracle
		/*
		uword       ecode;
		XMLParser   parser;
		ub4         flags = XML_FLAG_DISCARD_WHITESPACE;

		for (__int64 rind = 0; rind < rounds; ++rind)
		{
			parser.xmlinit();
			LARGE_INTEGER tbefore, tafter;
			::GetProcessMemoryInfo(h, &p, p.cb);
			__int64 mbefore = p.WorkingSetSize + p.PagefileUsage;

			QueryPerformanceCounter(&tbefore);
			parser.xmlparse((oratext *)(const char*)path, (oratext *) 0, flags);
			QueryPerformanceCounter(&tafter);
			::GetProcessMemoryInfo(h, &p, p.cb);
			__int64 mafter = p.WorkingSetSize + p.PagefileUsage;
				
			parser.xmlclean();
			memory_ += (mafter - mbefore);
			time_ += (tafter.QuadPart - tbefore.QuadPart) * 1000000 / ticks.QuadPart;
			parser.xmlterm();
		}

		*/

		// Xerces
		/*
		XMLPlatformUtils::Initialize();
		for (int index = 0; index < rounds; ++index)
		{
			XercesDOMParser *parser = new XercesDOMParser();
			parser->setValidationScheme(false);
			parser->setDoNamespaces(false);
			parser->setDoSchema(false);
			parser->setValidationSchemaFullChecking(false);
			parser->setCreateEntityReferenceNodes(false);


			try
			{
				parser->parse(file);
				parser->reset();
			}

			catch (...)
			{
				assert(false);
			}
			
			delete parser;
		}

		XMLPlatformUtils::Terminate();
		*/
		
		::SysFreeString(vpath.bstrVal);
		::CloseHandle(h);

		memory_ /= rounds;
		time_ /= rounds;
 
		printf("time: %d microsecond, memory: %d bytes", (int)time_, (int)memory_);

For reusing of object the follow test code was used:

		PROCESS_MEMORY_COUNTERS p;
		p.cb= sizeof(PROCESS_MEMORY_COUNTERS);
		HANDLE h = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ::GetCurrentProcessId());

		//Cstring path = "C:\xmltest\build1.xml";	
		//Cstring path = "C:\xmltest\build10.xml";	
		//Cstring path = "C:\xmltest\build100.xml";	
		//Cstring path = "C:\xmltest\build1000.xml";	
		//Cstring path = "C:\xmltest\build10000.xml";	

		//__int64 rounds = 1; - 100Mb file
		//__int64 rounds = 10; - 10Mb file
		//__int64 rounds = 100; - 1Mb file
		//__int64 rounds = 1000; - 100Kb file
		//__int64 rounds = 10000; - 10 Kb file

		__int64 memory_ = 0;
		__int64 time_ = 0;
		LARGE_INTEGER ticks;
		QueryPerformanceFrequency(&ticks);

		VARIANT_BOOL resVar;
		VARIANT vpath;
		vpath.bstrVal = path.AllocSysString();
		vpath.vt = VT_BSTR;

		/*
		//////////////// terimber

		const CLSID clsidt = {0xE9F698B3, 0xB48E, 0x4977, {0xA7, 0x73, 0x48, 0x95, 0xB8, 0x1C, 0x3D, 0x90}};
		const IID iidt = {0x3C11D17E, 0x5A2C, 0x446E, {0x9E, 0x9B, 0xF1, 0x28, 0x15, 0xC9, 0xD8, 0xB8}}; // IID_IXmlDesigner
		IXmlDesigner* p_IXmlDesigner = 0;
		HRESULT hr = ::CoCreateInstance(clsidt, 0, CLSCTX_INPROC_SERVER, iidt, (void**)&p_IXmlDesigner);

		for (__int64 rind = 0; rind < rounds; ++rind)
		{
			LARGE_INTEGER tbefore, tafter;
			::GetProcessMemoryInfo(h, &p, p.cb);
			__int64 mbefore = p.WorkingSetSize + p.PagefileUsage;

			QueryPerformanceCounter(&tbefore);
			hr = p_IXmlDesigner->load(vpath.bstrVal, 0, &resVar);
			QueryPerformanceCounter(&tafter);
			::GetProcessMemoryInfo(h, &p, p.cb);
			__int64 mafter = p.WorkingSetSize + p.PagefileUsage;
				
			memory_ += (mafter - mbefore);
			time_ += (tafter.QuadPart - tbefore.QuadPart) * 1000000 / ticks.QuadPart;
		}
		p_IXmlDesigner->Release();
	
		*/

		// microsoft
		/*
		const CLSID clsid = {0x88d969c0, 0xf192, 0x11d4, {0xa6, 0x5f, 0x00, 0x40, 0x96, 0x32, 0x51, 0xe5 }};
		const IID iid = {0x2933BF95, 0x7B36, 0x11d2, {0xB2,0x0E, 0x00, 0xC0, 0x4F, 0x98, 0x3E, 0x60}}; // IID_IXMLDOMDocument2
		IXMLDOMDocument2* p_IXMLDOMDocument2 = 0;
		HRESULT hr = ::CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, iid, (void**)&p_IXMLDOMDocument2);

		for (__int64 rind = 0; rind < rounds; ++rind)
		{
			LARGE_INTEGER tbefore, tafter;
			::GetProcessMemoryInfo(h, &p, p.cb);
			__int64 mbefore = p.WorkingSetSize + p.PagefileUsage;

			QueryPerformanceCounter(&tbefore);
			hr = p_IXMLDOMDocument2->load(vpath, &resVar);
			QueryPerformanceCounter(&tafter);
			::GetProcessMemoryInfo(h, &p, p.cb);
			__int64 mafter = p.WorkingSetSize + p.PagefileUsage;
				
			memory_ += mafter - mbefore;
			time_ += (tafter.QuadPart - tbefore.QuadPart) * 1000000 / ticks.QuadPart;
		}
		p_IXMLDOMDocument2->Release();

		*/

		// oracle
		/*
		uword       ecode;
		XMLParser   parser;
		ub4         flags = XML_FLAG_DISCARD_WHITESPACE;

		parser.xmlinit();
		for (__int64 rind = 0; rind < rounds; ++rind)
		{
			LARGE_INTEGER tbefore, tafter;
			::GetProcessMemoryInfo(h, &p, p.cb);
			__int64 mbefore = p.WorkingSetSize + p.PagefileUsage;

			QueryPerformanceCounter(&tbefore);
			parser.xmlparse((oratext *)(const char*)path, (oratext *) 0, flags);
			QueryPerformanceCounter(&tafter);
			::GetProcessMemoryInfo(h, &p, p.cb);
			__int64 mafter = p.WorkingSetSize + p.PagefileUsage;
				
			parser.xmlclean();
			memory_ += (mafter - mbefore);
			time_ += (tafter.QuadPart - tbefore.QuadPart) * 1000000 / ticks.QuadPart;
		}
		parser.xmlterm();

		*/

		// Xerces
		// this code works, however the memory isn't released or reused
		/*
		XMLPlatformUtils::Initialize();
		XercesDOMParser *parser = new XercesDOMParser();
		parser->setValidationScheme(false);
		parser->setDoNamespaces(false);
		parser->setDoSchema(false);
		parser->setValidationSchemaFullChecking(false);
		parser->setCreateEntityReferenceNodes(false);

		for (int index = 0; index < rounds; ++index)
		{

			try
			{
				parser->parse(file);
				parser->reset();
			}

			catch (...)
			{
				assert(false);
			}
			
		}
		delete parser;
		XMLPlatformUtils::Terminate();
		*/

		
		::SysFreeString(vpath.bstrVal);
		::CloseHandle(h);

		memory_ /= rounds;
		time_ /= rounds;
 
		printf("time: %d microsecond, memory: %d bytes", (int)time_, (int)memory_); 



© Copyright Terimber 2003-.