locked
Calling methods on WinRT classes

    Question

  • Hello, I was experimenting with smart pointers. VC++ generates AddRef and Release for WinRT classes and sometimes these calls are optimized out. This is not the case with shared_ptr because it has no compiler support. Because my C++ codebase uses STL containers and smart pointers I tried to replace shared_ptr by a WinRT class. Everything works as expected and it's way faster to work with containers (because copy constructors can be avoided) but the overloaded -> operator is significantly slower for the WinRT class. Is it because it's compiled to a virtual function? Can this be avoided? Here's the WinRT class:

    template<typename T> ref class SharedPtr {
    private:
    T* obj;
    public:
    SharedPtr(T* o) : obj(o) {}
    ~SharedPtr() { delete obj; }
    T* operator->() { return obj; }
    T& operator*() { return *obj; }
    };

    Friday, November 04, 2011 10:48 AM

All replies

  • WinRT calls will be be COM calls (thus virtual and a tad slower). So that probably explains what you see.

     

    That said, why do you want to use a smart pointer with hats? They are already ref-counted and so what would you achieve by using them with shared_ptr?


    http://blog.voidnish.com
    Friday, November 04, 2011 2:54 PM
  • I have C++ classes and I use them with shared_ptr. I've replaced shared_ptr by SharedPtr which is a WinRT class. In other words SharedPtr a ref counted WinRT class that wraps a "plain" C++ class.
    Friday, November 04, 2011 4:17 PM
  • I have C++ classes and I use them with shared_ptr. I've replaced shared_ptr by SharedPtr which is a WinRT class. In other words SharedPtr a ref counted WinRT class that wraps a "plain" C++ class.


    shared_ptr is sure to be as (or more) efficient than ref-counted WinRT types (even with the AddRef/Release optimizations).  If you are not seeing that, then something else in your implementation may be the problem.


    http://blog.voidnish.com
    Friday, November 04, 2011 8:03 PM
  • shared_ptr op*() and op->() are literally zero-overhead - they just dereference a raw pointer, so when they're fully inlined they have no other penalties.

    If WinRT imposes any overheads (and I'm not an expert on WinRT's underlying magic), then that's certainly greater than zero.

    I don't understand what you're trying to achieve with your SharedPtr. You said "This is not the case with shared_ptr because it has no compiler support." but shared_ptr implements move semantics, so vector<shared_ptr<T>> reallocation performs zero interlocked operations.  When passing shared_ptrs around, they should be passed by const shared_ptr<T>&, to avoid unnecessary copies (shared_ptr copies are much cheaper than vector copies but they're still not free).

    In related news, I recently discovered that shared_ptr copying was unnecessarily expensive in VC10, and got worse in VC11. (We called the wrong helper function, an expensive one meant only for weak_ptr locking to shared_ptr.) I'm checking in a fix today that improves our perf to better than VC10, and almost as good as Boost. (There's a remaining issue which I'll be attacking later.)

    Friday, November 04, 2011 11:15 PM