Skip to content

Commit

Permalink
refactor(core): Use binary search for the ns0 type lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
jpfr committed Jan 20, 2024
1 parent 21ec9f3 commit fe7831e
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 8 deletions.
23 changes: 15 additions & 8 deletions src/ua_types.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
21 changes: 21 additions & 0 deletions tests/check_types_builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "ua_util_internal.h"

#include <stdlib.h>
#include <stdio.h>
#include <check.h>
#include <float.h>
#include <math.h>
Expand Down Expand Up @@ -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");

Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit fe7831e

Please sign in to comment.