Good morning everyone,
whilst implementing a new feature in VTK
, one of my colleague had performance issues w.r.t. to array type conversion. More precisely, he was casting something to a vtkFloatArray
using the vtkArrayDownCast
template function. After looking at the code, this function is nothing but a paththrough to the internal SafeDownCast
function contained in every vtk object. The function looks like this and can be found here:
static vtkTypeBool IsTypeOf(const char* type) \
{ \
if (!strcmp(thisClassName, type)) \
{ \
return 1; \
} \
return superclass::IsTypeOf(type); \
} \
vtkTypeBool IsA(const char* type) override { return this->thisClass::IsTypeOf(type); } \
static thisClass* SafeDownCast(vtkObjectBase* o) \
{ \
if (o && o->IsA(thisClassName)) \
{ \
return static_cast<thisClass*>(o); \
} \
return nullptr; \
}
Looking at the code, it is clear that the IsTypeOf
function is the culprit for two reasons:
- the call to
strcmp
- the recursion when
strcmp
succeeds
This results in multiple branching recursive calls, which can be costly (especially if the SafeDownCast
is called multiple times in a row).
One potential, and easy to implement method that we could add the VTK is the UString
type (see here). Quoting the comments:
/// A ustring is an alternative to char* or std::string for storing
/// strings, in which the character sequence is unique (allowing many
/// speed advantages for assignment, equality testing, and inequality
/// testing).
///
/// The implementation is that behind the scenes there is a hash set of
/// allocated strings, so the characters of each string are unique. A
/// ustring itself is a pointer to the characters of one of these canonical
/// strings. Therefore, assignment and equality testing is just a single
/// 32- or 64-bit int operation, the only mutex is when a ustring is
/// created from raw characters, and the only malloc is the first time
/// each canonical ustring is created.
This new type could be use in place of the const char*
used for the internal type, and we could then replace the strcmp
used in IsTypeOf
. Although I’ve not tested it, I’m 90% sure we would get performance improvements (this is based on personal knowledge from my other projects). Also, if we can get some improvements, this would affect a lot VTK (and paraview) as VTK has 5664 calsd to this function and paraview 48449
Tell me what you think!