eo: speedup efl_isa by 50%.
authorCedric BAIL <cedric@osg.samsung.com>
Fri, 26 Aug 2016 19:04:23 +0000 (12:04 -0700)
committerCedric BAIL <cedric@osg.samsung.com>
Fri, 26 Aug 2016 19:14:14 +0000 (12:14 -0700)
Most of our use case of efl_isa is related to legacy Evas_Object_Image API,
that check the isa of the same object again and again. Caching help.

src/lib/eo/eo.c
src/lib/eo/eo_ptr_indirection.x

index b5354c0..f8eaaf4 100644 (file)
@@ -1433,17 +1433,31 @@ efl_object_override(Eo *eo_id, const Efl_Object_Ops *ops)
    return EINA_TRUE;
 }
 
+const Eo *cached_isa_id = NULL;
+
+static const Efl_Class *cached_klass = NULL;
+static Eina_Bool cached_isa = EINA_FALSE;
+
 EAPI Eina_Bool
 efl_isa(const Eo *eo_id, const Efl_Class *klass_id)
 {
+   if (cached_isa_id == eo_id && cached_klass == klass_id)
+     return cached_isa;
+
    EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, EINA_FALSE);
    EO_CLASS_POINTER_RETURN_VAL(klass_id, klass, EINA_FALSE);
    const op_type_funcs *func = _vtable_func_get(obj->vtable,
          klass->base_id + klass->desc->ops.count);
 
+   // Caching the result as we do a lot of serial efl_isa due to evas_object_image using it.
+   cached_isa_id = eo_id;
+   cached_klass = klass_id;
+
    /* Currently implemented by reusing the LAST op id. Just marking it with
     * _eo_class_isa_func. */
-   return (func && (func->func == _eo_class_isa_func));
+   cached_isa = (func && (func->func == _eo_class_isa_func));
+
+   return cached_isa;
 }
 
 EAPI Eo *
index cae59a4..2f95e64 100644 (file)
@@ -445,6 +445,8 @@ _eo_id_allocate(const _Eo_Object *obj)
 #endif
 }
 
+extern const Eo *cached_isa_id;
+
 static inline void
 _eo_id_release(const Eo_Id obj_id)
 {
@@ -494,6 +496,7 @@ _eo_id_release(const Eo_Id obj_id)
              // In case an object is destroyed, wipe out the cache
              cached_id = 0;
              cached_object = NULL;
+             cached_isa_id = NULL;
 
              return;
           }