How fast is CreateInstance? 
Author Message
 How fast is CreateInstance?

Hello All,

I was recently thinking how fast is the ATL implementation of CreateInstance
(or at least Windows API's CreateInstance) say comparing with raw new
operator?
As far as I know COM basics the CreateInstance (or Class Factory) should
perform kind of registry look up to find a string containing GUID and I find
the routine to be long enough. Or may be registry is stored in some
indexed/hashed way so that the search is optimized.

Dmitri Zhukov



Sun, 04 Sep 2005 16:30:15 GMT  
 How fast is CreateInstance?
Hi Dmitri,

Quote:
> I was recently thinking how fast is the ATL implementation of
CreateInstance
> (or at least Windows API's CreateInstance) say comparing with raw new
> operator?

If you mean CoCreateInstance, there is the overhead of locating the class
factory for the object, but only at the first request, after which COM
caches the factory, IIRC.

The flow of events should be something like this:

- Take the passed in CLSID and look it up in the registry under HKCR\CLSID
- Get the InprocServer32 (for inproc servers) value, pointing to the DLL in
question
- Load the DLL, and keep it loaded
- Call DllGetClassObject, passing in the CLSID
- IClassFactory implementation is returned
- Call IClassFactory::CreateInstance
- The factory implementation uses some mem allocation technique (new), and
calls your object's FinalConstruct

There's no telling how much of the information is cached, that's basically
an implementation detail. You could test by comparing CoCreateInstance vs
CComObject<>::CreateInstance on one of your objects.

CComObject<>::CreateInstance, is basically equivalent to new + anything your
object does in FinalConstruct.

--
Best regards,
Kim Gr?sman


Quote:
> Hello All,

> I was recently thinking how fast is the ATL implementation of
CreateInstance
> (or at least Windows API's CreateInstance) say comparing with raw new
> operator?
> As far as I know COM basics the CreateInstance (or Class Factory) should
> perform kind of registry look up to find a string containing GUID and I
find
> the routine to be long enough. Or may be registry is stored in some
> indexed/hashed way so that the search is optimized.

> Dmitri Zhukov



Sun, 04 Sep 2005 16:55:34 GMT  
 How fast is CreateInstance?
Ok thanx Kim,

you described the whole picture just as I've expected it to be. I need to be
able to create thousands of objects quickly enough
and I can do it quickly as long as ClassFactory's instance is not released
from the memory. And what is important the creation is done
on server side so I can take advantage of CComObject::CreateInstance since I
have access to CComObjectRoot.

Dmitri



Quote:
> Hi Dmitri,

> > I was recently thinking how fast is the ATL implementation of
> CreateInstance
> > (or at least Windows API's CreateInstance) say comparing with raw new
> > operator?

> If you mean CoCreateInstance, there is the overhead of locating the class
> factory for the object, but only at the first request, after which COM
> caches the factory, IIRC.

> The flow of events should be something like this:

> - Take the passed in CLSID and look it up in the registry under HKCR\CLSID
> - Get the InprocServer32 (for inproc servers) value, pointing to the DLL
in
> question
> - Load the DLL, and keep it loaded
> - Call DllGetClassObject, passing in the CLSID
> - IClassFactory implementation is returned
> - Call IClassFactory::CreateInstance
> - The factory implementation uses some mem allocation technique (new), and
> calls your object's FinalConstruct

> There's no telling how much of the information is cached, that's basically
> an implementation detail. You could test by comparing CoCreateInstance vs
> CComObject<>::CreateInstance on one of your objects.

> CComObject<>::CreateInstance, is basically equivalent to new + anything
your
> object does in FinalConstruct.

> --
> Best regards,
> Kim Gr?sman



> > Hello All,

> > I was recently thinking how fast is the ATL implementation of
> CreateInstance
> > (or at least Windows API's CreateInstance) say comparing with raw new
> > operator?
> > As far as I know COM basics the CreateInstance (or Class Factory) should
> > perform kind of registry look up to find a string containing GUID and I
> find
> > the routine to be long enough. Or may be registry is stored in some
> > indexed/hashed way so that the search is optimized.

> > Dmitri Zhukov



Sun, 04 Sep 2005 17:06:05 GMT  
 How fast is CreateInstance?
Dmitri,

Quote:
> And what is important the creation is done
> on server side so I can take advantage of CComObject::CreateInstance since
I
> have access to CComObjectRoot.

I'm not sure what you mean... You can use CComObject<>::CreateInstance only
if you have source code access to the implementation class.

I suspect testing is the only way for you to find out which model suits you
best.

--
Best regards,
Kim Gr?sman


Quote:
> Ok thanx Kim,

> you described the whole picture just as I've expected it to be. I need to
be
> able to create thousands of objects quickly enough
> and I can do it quickly as long as ClassFactory's instance is not released
> from the memory. And what is important the creation is done
> on server side so I can take advantage of CComObject::CreateInstance since
I
> have access to CComObjectRoot.

> Dmitri



> > Hi Dmitri,

> > > I was recently thinking how fast is the ATL implementation of
> > CreateInstance
> > > (or at least Windows API's CreateInstance) say comparing with raw new
> > > operator?

> > If you mean CoCreateInstance, there is the overhead of locating the
class
> > factory for the object, but only at the first request, after which COM
> > caches the factory, IIRC.

> > The flow of events should be something like this:

> > - Take the passed in CLSID and look it up in the registry under
HKCR\CLSID
> > - Get the InprocServer32 (for inproc servers) value, pointing to the DLL
> in
> > question
> > - Load the DLL, and keep it loaded
> > - Call DllGetClassObject, passing in the CLSID
> > - IClassFactory implementation is returned
> > - Call IClassFactory::CreateInstance
> > - The factory implementation uses some mem allocation technique (new),
and
> > calls your object's FinalConstruct

> > There's no telling how much of the information is cached, that's
basically
> > an implementation detail. You could test by comparing CoCreateInstance
vs
> > CComObject<>::CreateInstance on one of your objects.

> > CComObject<>::CreateInstance, is basically equivalent to new + anything
> your
> > object does in FinalConstruct.

> > --
> > Best regards,
> > Kim Gr?sman



> > > Hello All,

> > > I was recently thinking how fast is the ATL implementation of
> > CreateInstance
> > > (or at least Windows API's CreateInstance) say comparing with raw new
> > > operator?
> > > As far as I know COM basics the CreateInstance (or Class Factory)
should
> > > perform kind of registry look up to find a string containing GUID and
I
> > find
> > > the routine to be long enough. Or may be registry is stored in some
> > > indexed/hashed way so that the search is optimized.

> > > Dmitri Zhukov



Sun, 04 Sep 2005 17:13:59 GMT  
 How fast is CreateInstance?

Quote:

> Hello All,

> I was recently thinking how fast is the ATL implementation of CreateInstance
> (or at least Windows API's CreateInstance) say comparing with raw new
> operator?
> As far as I know COM basics the CreateInstance (or Class Factory) should
> perform kind of registry look up to find a string containing GUID and I find
> the routine to be long enough. Or may be registry is stored in some
> indexed/hashed way so that the search is optimized.

The IClassFactory::CreateInstance don't perform any kind of registry
look-up. Its task is the creation of object.

The COM makes the registry look-up to get the Class Factory object to
client.

All overhead is
template <class T1> class CComCreator
{
public:
        static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID*
ppv)
        {
                ATLASSERT(*ppv == NULL);
                HRESULT hRes = E_OUTOFMEMORY;
                T1* p = NULL;
                ATLTRY(p = new T1(pv))
                if (p != NULL)
                {
                        p->SetVoid(pv);
                        p->InternalFinalConstructAddRef();
                        hRes = p->FinalConstruct();
                        p->InternalFinalConstructRelease();
                        if (hRes == S_OK)
                                hRes = p->QueryInterface(riid, ppv);
                        if (hRes != S_OK)
                                delete p;
                }
                return hRes;
        }

Quote:
};



Sun, 04 Sep 2005 22:40:07 GMT  
 How fast is CreateInstance?
It seems I was no not quite correct asking the question. I meant that for
the COM client

 to get Class Factory itself - this requires registry look up.




Quote:
> > Hello All,

> > I was recently thinking how fast is the ATL implementation of
CreateInstance
> > (or at least Windows API's CreateInstance) say comparing with raw new
> > operator?
> > As far as I know COM basics the CreateInstance (or Class Factory) should
> > perform kind of registry look up to find a string containing GUID and I
find
> > the routine to be long enough. Or may be registry is stored in some
> > indexed/hashed way so that the search is optimized.

> The IClassFactory::CreateInstance don't perform any kind of registry
> look-up. Its task is the creation of object.

> The COM makes the registry look-up to get the Class Factory object to
> client.

> All overhead is
> template <class T1> class CComCreator
> {
> public:
> static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID*
> ppv)
> {
> ATLASSERT(*ppv == NULL);
> HRESULT hRes = E_OUTOFMEMORY;
> T1* p = NULL;
> ATLTRY(p = new T1(pv))
> if (p != NULL)
> {
> p->SetVoid(pv);
> p->InternalFinalConstructAddRef();
> hRes = p->FinalConstruct();
> p->InternalFinalConstructRelease();
> if (hRes == S_OK)
> hRes = p->QueryInterface(riid, ppv);
> if (hRes != S_OK)
> delete p;
> }
> return hRes;
> }
> };



Sun, 04 Sep 2005 23:02:04 GMT  
 How fast is CreateInstance?
You can use CoGetClassObject instead of CoCreateInstance - COM will
follow all the same steps up to the point where it obtains
IClassFactory, which it promptly returns to you. You can hang on to
IClassFactory pointer and call IClassFactory::CreateInstance as many
times and as often as you want. For an in-proc server, this is going to
be just one extra virtual call before the server performs "new" on the
object, a price you have to pay for binary compatibility and language
independence.
--
With best wishes,
    Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken


Quote:
> Ok thanx Kim,

> you described the whole picture just as I've expected it to be. I need
to be
> able to create thousands of objects quickly enough
> and I can do it quickly as long as ClassFactory's instance is not
released
> from the memory. And what is important the creation is done
> on server side so I can take advantage of CComObject::CreateInstance
since I
> have access to CComObjectRoot.

> Dmitri


?????

> > Hi Dmitri,

> > > I was recently thinking how fast is the ATL implementation of
> > CreateInstance
> > > (or at least Windows API's CreateInstance) say comparing with raw
new
> > > operator?

> > If you mean CoCreateInstance, there is the overhead of locating the
class
> > factory for the object, but only at the first request, after which
COM
> > caches the factory, IIRC.

> > The flow of events should be something like this:

> > - Take the passed in CLSID and look it up in the registry under
HKCR\CLSID
> > - Get the InprocServer32 (for inproc servers) value, pointing to the
DLL
> in
> > question
> > - Load the DLL, and keep it loaded
> > - Call DllGetClassObject, passing in the CLSID
> > - IClassFactory implementation is returned
> > - Call IClassFactory::CreateInstance
> > - The factory implementation uses some mem allocation technique
(new), and
> > calls your object's FinalConstruct

> > There's no telling how much of the information is cached, that's
basically
> > an implementation detail. You could test by comparing
CoCreateInstance vs
> > CComObject<>::CreateInstance on one of your objects.

> > CComObject<>::CreateInstance, is basically equivalent to new +
anything
> your
> > object does in FinalConstruct.

> > --
> > Best regards,
> > Kim Gr?sman



> > > Hello All,

> > > I was recently thinking how fast is the ATL implementation of
> > CreateInstance
> > > (or at least Windows API's CreateInstance) say comparing with raw
new
> > > operator?
> > > As far as I know COM basics the CreateInstance (or Class Factory)
should
> > > perform kind of registry look up to find a string containing GUID
and I
> > find
> > > the routine to be long enough. Or may be registry is stored in
some
> > > indexed/hashed way so that the search is optimized.

> > > Dmitri Zhukov



Mon, 05 Sep 2005 00:52:10 GMT  
 How fast is CreateInstance?

Quote:

> Hello All,

> I was recently thinking how fast is the ATL implementation of CreateInstance
> (or at least Windows API's CreateInstance) say comparing with raw new
> operator?
> As far as I know COM basics the CreateInstance (or Class Factory) should
> perform kind of registry look up to find a string containing GUID and I find
> the routine to be long enough. Or may be registry is stored in some
> indexed/hashed way so that the search is optimized.

> Dmitri Zhukov

If you've ever used MSXML, you'll realize that there's a lot of COM
objects that are created that you can't CoCreateInstance even if you
wanted to.  For example, each node in an XML DOM (with MSXML) is a COM
object.  You create them by calling some "factory" method
(IXMLDOMDocument::createNode for example), or they get created
automatically when loading a document.

On a previous product we had an object model that I did some performance
testing on with TrueTime.  There were thousands of COM objects being
created.  The results showed that CoCreateInstance was a *huge*
bottleneck.  If you have access to the source, its *much* faster to use:

        CComObject<CMyClass>* pObject;
        hr = CComObject<CMyClass>::CreateInstance(&pObject);

but just beware that CreateInstance doesn't AddRef the object for you,
so you need to AddRef it, or QI (or something that does this for you
like CComPtr) as soon as possible to keep it alive.

Another alternative to CComObject, assuming your COM objects are
implemented in a DLL, is to use this little function I wrote that will
use a local class factory if possible, and CoCreateInstance if not
(watch for line wraps):

HRESULT LocalCreateInstance(REFCLSID rclsid, REFIID riid, void** ppObj)
{
        if(ppObj==NULL)
        {
                return E_POINTER;
        }
        *ppObj = NULL;

        HRESULT hr = S_OK;

        CComPtr<IClassFactory> pCF;
#if (_ATL_VER < 0x0700)
        hr = _Module.GetClassObject(
                rclsid,
                IID_IClassFactory,
                (void**)&pCF);
#else
        hr = _pModule->GetClassObject(
                rclsid,
                IID_IClassFactory,
                (void**)&pCF);
#endif
        if(SUCCEEDED(hr))
        {
                hr = pCF->CreateInstance(
                                NULL,
                                riid,
                                ppObj);
        }

        if(FAILED(hr))
        {
                hr = ::CoCreateInstance(
                        rclsid,
                        NULL,
                        CLSCTX_SERVER,
                        riid,
                        ppObj);
        }

        return hr;

Quote:
}

 From my profiling, using this function was anywhere from 10%-40% faster
in Release and 30%-60% faster in Debug than a full CoCreateInstance.

You'd then use this similar to CoCreateInstance:

        CComPtr<IMyInterface> pObject;
        hr = ::LocalCreateInstance(
                clsid,
                IID_IMyInterface,
                (void**)&pObject);

HTH,
-Daniel



Mon, 05 Sep 2005 02:45:17 GMT  
 How fast is CreateInstance?

Quote:
> It seems I was no not quite correct asking the question. I meant that for
> the COM client

>  to get Class Factory itself - this requires registry look up.

You want to avoid even that? You can do without...
Just run LoadLibrary, GetProcaddress for DllGetClassObject. The DLL location
must be known of course...
Quote:








Mon, 05 Sep 2005 06:17:06 GMT  
 How fast is CreateInstance?


Quote:


> > It seems I was no not quite correct asking the question. I meant
that for
> > the COM client

> >  to get Class Factory itself - this requires registry look up.
> You want to avoid even that? You can do without...
> Just run LoadLibrary, GetProcaddress for DllGetClassObject. The DLL
location
> must be known of course...

It's better to use CoLoadLibrary. Then COM takes responsibility for
freeing the DLL at the appropriate time.
--
With best wishes,
    Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken



Mon, 05 Sep 2005 06:20:51 GMT  
 How fast is CreateInstance?
Just a tiny detail, you have to call IClassFactory::LockServer(TRUE) to
ensure your server will stay loaded. Unlike regular objects, class
objects do not keep the server alive... You need to match with
IClassFactory::LockServer(FALSE) when it's not needed anymore.

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD

MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================

Quote:

> You can use CoGetClassObject instead of CoCreateInstance - COM will
> follow all the same steps up to the point where it obtains
> IClassFactory, which it promptly returns to you. You can hang on to
> IClassFactory pointer and call IClassFactory::CreateInstance as many
> times and as often as you want. For an in-proc server, this is going to
> be just one extra virtual call before the server performs "new" on the
> object, a price you have to pay for binary compatibility and language
> independence.
> --
> With best wishes,
>     Igor Tandetnik

> "For every complex problem, there is a solution that is simple, neat,
> and wrong." H.L. Mencken



> > Ok thanx Kim,

> > you described the whole picture just as I've expected it to be. I need
> to be
> > able to create thousands of objects quickly enough
> > and I can do it quickly as long as ClassFactory's instance is not
> released
> > from the memory. And what is important the creation is done
> > on server side so I can take advantage of CComObject::CreateInstance
> since I
> > have access to CComObjectRoot.

> > Dmitri


> ?????

> > > Hi Dmitri,

> > > > I was recently thinking how fast is the ATL implementation of
> > > CreateInstance
> > > > (or at least Windows API's CreateInstance) say comparing with raw
> new
> > > > operator?

> > > If you mean CoCreateInstance, there is the overhead of locating the
> class
> > > factory for the object, but only at the first request, after which
> COM
> > > caches the factory, IIRC.

> > > The flow of events should be something like this:

> > > - Take the passed in CLSID and look it up in the registry under
> HKCR\CLSID
> > > - Get the InprocServer32 (for inproc servers) value, pointing to the
> DLL
> > in
> > > question
> > > - Load the DLL, and keep it loaded
> > > - Call DllGetClassObject, passing in the CLSID
> > > - IClassFactory implementation is returned
> > > - Call IClassFactory::CreateInstance
> > > - The factory implementation uses some mem allocation technique
> (new), and
> > > calls your object's FinalConstruct

> > > There's no telling how much of the information is cached, that's
> basically
> > > an implementation detail. You could test by comparing
> CoCreateInstance vs
> > > CComObject<>::CreateInstance on one of your objects.

> > > CComObject<>::CreateInstance, is basically equivalent to new +
> anything
> > your
> > > object does in FinalConstruct.

> > > --
> > > Best regards,
> > > Kim Gr?sman



> > > > Hello All,

> > > > I was recently thinking how fast is the ATL implementation of
> > > CreateInstance
> > > > (or at least Windows API's CreateInstance) say comparing with raw
> new
> > > > operator?
> > > > As far as I know COM basics the CreateInstance (or Class Factory)
> should
> > > > perform kind of registry look up to find a string containing GUID
> and I
> > > find
> > > > the routine to be long enough. Or may be registry is stored in
> some
> > > > indexed/hashed way so that the search is optimized.

> > > > Dmitri Zhukov



Tue, 06 Sep 2005 03:57:52 GMT  
 
 [ 11 post ] 

 Relevant Pages 

1. HELP with C, I am losing it fast....

2. I am new to programming and am lost

3. faster strcat (and/or faster string append in C++)

4. faster,faster

5. Faster faster

6. Assembly.CreateInstance returns a type that generates InvalidCastException when typecasted

7. Activator.CreateInstance

8. Activator.CreateInstance() for OleDbConnection

9. Assembly.CreateInstance

10. notifying a singleton of createinstance

11. Problems creating a valid object using CComObject<...>::CreateInstance

12. ADO: CreateInstance on ConnectionPtr.

 

 
Powered by phpBB® Forum Software