My application can do many thousands or even millions of ice_isA calls. In C++, each ice_isA call generated by slice2cpp does a std::binary_search over the names of the base classes which causes operator< on a std::string to be executed several times for each such call. The deeper the inheritance graph, the more operator< calls will be made. While this isn't horrible, it does have a performance impact when it is called so many times. Consequently I removed the use of ice_isA from my program and implemented it more quickly using pointer comparison. This gave my application a significant performance boost.
Because each class is identified by a static string, it is possible to use pointer comparison on the address of the static string rather than do whole string comparisons. This would also eliminate redundant strings for the same class. Because operator< for a pointer is significantly faster than operator< for a std::string, there is a significant performance improvement in ice_isA if it compare the address of the class names rather than the class names themselves.
Implementing this would be a bit of work, but shouldn't be too bad. The main points are:
- Only generate one static std::string object for each class.
- Populate the __Class__ids array with addresses of the strings for the necessary class by making calls to Class::ice_staticId
- When comparing items in the _ids array make sure take the address of _s to compare against pointers.
- When returning items from the _ids array, dereference the pointer.
The only down side of this approach is that the user cannot specify an arbitrary string to ice_isA. That shouldn't be a problem in practice because the caller should only be passing in the result of Class::ice_staticId() calls anyway.
I have considered patching slice2cpp to implement the above. It would save me a few hundred lines of code that I've written on the side and it would work on anything I generate with slice2cpp without needing to maintain my side implementation.
Another idea is to use some template magic to achieve the same thing with very little overhead and even better performance. The mechanism I have in mind is implemented in the casting.h header of the LLVM project.
If zeroc.com is interested in either such a patch, please let me know and I'll consider contributing it.

Reply With Quote