diff --git a/src/ua_types.c b/src/ua_types.c index 62441bbc116..04104143a44 100644 --- a/src/ua_types.c +++ b/src/ua_types.c @@ -63,14 +63,21 @@ guidOrder(const UA_Guid *p1, const UA_Guid *p2, const UA_DataType *_); const UA_DataType * UA_findDataTypeWithCustom(const UA_NodeId *typeId, const UA_DataTypeArray *customTypes) { - /* Always look in built-in types first (may contain data types from all - * namespaces). - * - * TODO: The standard-defined types are ordered. See if binary search is - * more efficient. */ - for(size_t i = 0; i < UA_TYPES_COUNT; ++i) { - if(nodeIdOrder(&UA_TYPES[i].typeId, typeId, NULL) == UA_ORDER_EQ) - return &UA_TYPES[i]; + /* Always look in UA_TYPES first. UA_TYPES is ordered and contains only + * types from ns0 with a numeric identifier. So we can use binary search to + * speed this up. */ + if(typeId->namespaceIndex == 0 && typeId->identifierType == UA_NODEIDTYPE_NUMERIC) { + size_t first = 0; + size_t last = UA_TYPES_COUNT - 1; + while(first <= last) { + size_t middle = (first+last) >> 1; + if(UA_TYPES[middle].typeId.identifier.numeric == typeId->identifier.numeric) + return &UA_TYPES[middle]; + if(UA_TYPES[middle].typeId.identifier.numeric < typeId->identifier.numeric) + first = middle + 1; + else + last = middle - 1; + } } /* Search in the customTypes */ diff --git a/tests/check_types_builtin.c b/tests/check_types_builtin.c index 7570de39df1..ff942b6957e 100644 --- a/tests/check_types_builtin.c +++ b/tests/check_types_builtin.c @@ -10,6 +10,7 @@ #include "ua_util_internal.h" #include +#include #include #include #include @@ -1711,6 +1712,22 @@ START_TEST(UA_StatusCode_utils) { } END_TEST +START_TEST(UA_type_lookup_speed) { + clock_t begin, finish; + begin = clock(); + + UA_NodeId readRequestId = UA_TYPES[UA_TYPES_READREQUEST].typeId; + + for(size_t i = 0; i < 1000; i++) { + const UA_DataType *t = UA_findDataType(&readRequestId); + ck_assert(t == &UA_TYPES[UA_TYPES_READREQUEST]); + } + + finish = clock(); + double time_spent = (double)(finish - begin) / CLOCKS_PER_SEC; + printf("duration of the type lookup was %f s\n", time_spent); +} END_TEST + static Suite *testSuite_builtin(void) { Suite *s = suite_create("Built-in Data Types 62541-6 Table 1"); @@ -1803,6 +1820,10 @@ static Suite *testSuite_builtin(void) { tcase_add_test(tc_utils, UA_StatusCode_utils); suite_add_tcase(s, tc_utils); + TCase *tc_speed = tcase_create("speed"); + tcase_add_test(tc_speed, UA_type_lookup_speed); + suite_add_tcase(s, tc_speed); + return s; }