Hi support team,
we are unsure about the decision between numeric node ids or string node ids.
For performance reasons we decided to use numeric ids. However because in our UA server implementation the numeric ids are recalculated on each run it is possible that a node id might change after a server restart for logically the same node.
Is this implementation correct or should we use string ids instead, holding the logical name of the node?
Best regards
Kurt
Numeric NodeId vs. String NodeId
Moderator: Support Team
- Support Team
- Hero Member
- Posts: 3070
- Joined: 18 Mar 2011, 15:09
Re:Numeric NodeId vs. String NodeId
Hi Kurt,
The first and most important rule is that NodeIds are not allowed to change on server restart if the node is logically still the same. This will be a major problem for most real OPC UA clients since they will persist the NodeIds during configuration and will reuse them later on. This is typical for HMI clients.
Numeric NodeIds are used for static nodes that do not change e.g. for type systems, generated code or nodes baked into a firmware of an embedded device. The UaModeler is using numeric NodeIds for the generated code.
String NodeIds are used for dynamic systems since it is normally easy to recalculate the same NodeId at every server start based on names in the hierarchy.
GUID NodeIds are used if it must be ensured that they are globally unique.
OPC UA provides the services RegisterNodes and UnregisterNodes to optimize access to nodes. A server should return numeric NodeIds as the registered NodeIds to optimize access. The C++ and .NET SDK are doing this automatically. There is nothing you need to implement for this feature in a C++ or .NET SDK based server.
Best Regards
Unified Automation Support Team
The first and most important rule is that NodeIds are not allowed to change on server restart if the node is logically still the same. This will be a major problem for most real OPC UA clients since they will persist the NodeIds during configuration and will reuse them later on. This is typical for HMI clients.
Numeric NodeIds are used for static nodes that do not change e.g. for type systems, generated code or nodes baked into a firmware of an embedded device. The UaModeler is using numeric NodeIds for the generated code.
String NodeIds are used for dynamic systems since it is normally easy to recalculate the same NodeId at every server start based on names in the hierarchy.
GUID NodeIds are used if it must be ensured that they are globally unique.
OPC UA provides the services RegisterNodes and UnregisterNodes to optimize access to nodes. A server should return numeric NodeIds as the registered NodeIds to optimize access. The C++ and .NET SDK are doing this automatically. There is nothing you need to implement for this feature in a C++ or .NET SDK based server.
Best Regards
Unified Automation Support Team
Best regards
Unified Automation Support Team
Unified Automation Support Team
-
- Jr. Member
- Posts: 1
- Joined: 23 Feb 2015, 11:07
Re: Numeric NodeId vs. String NodeId
Dear support team,
I am experiencing a performance issue related to (String) NodeIds in particularly creating alarm nodes.
Indeed internally the alarm nodes provide a lot of instance-declared properties (class UaVariableAttributesInstanceDeclaration).
The implentation of nodeId method for these objects does not provide any caching/reference counting since the nodeId is recomputed every time the function is called as a brand new string:
So when it comes to add a new node to the nodemanager and the hash table of nodes needs to be looked up I can observe a storm of calls to the above very ineffient nodeId() implementation and the net result is an unacceptable loading time (up to minutes in our embedded target for 2000 alarms).
Is it safe to unset the define USE_MEMORY_OPTIMIZED_PARENT_POINTER ? What kind of side effects can I expect? Is there any other cleaner solution?
Best Regards,
Arrigo
I am experiencing a performance issue related to (String) NodeIds in particularly creating alarm nodes.
Indeed internally the alarm nodes provide a lot of instance-declared properties (class UaVariableAttributesInstanceDeclaration).
The implentation of nodeId method for these objects does not provide any caching/reference counting since the nodeId is recomputed every time the function is called as a brand new string:
Code: Select all
#if USE_MEMORY_OPTIMIZED_PARENT_POINTER
return UaNodeId(UaString("%1.%2").arg(m_pParentNode->nodeId().toString()).arg(m_pVariable->browseName().toString()), m_pParentNode->nodeId().namespaceIndex());
#else // USE_MEMORY_OPTIMIZED_PARENT_POINTER
return m_nodeId;
#endif // USE_MEMORY_OPTIMIZED_PARENT_POINTER
Is it safe to unset the define USE_MEMORY_OPTIMIZED_PARENT_POINTER ? What kind of side effects can I expect? Is there any other cleaner solution?
Best Regards,
Arrigo
- Support Team
- Hero Member
- Posts: 3070
- Joined: 18 Mar 2011, 15:09
Re: Numeric NodeId vs. String NodeId
Hello zanettea,
This is just a way to optimise memory consumption for InstanceDeclarationNodes by storing the parent pointer instead of the NodeId and generate the NodeId on the fly whenever it is needed. You can savely change the setting to OPCUA_CONFIG_NO.
This is just a way to optimise memory consumption for InstanceDeclarationNodes by storing the parent pointer instead of the NodeId and generate the NodeId on the fly whenever it is needed. You can savely change the setting to OPCUA_CONFIG_NO.
Best regards
Unified Automation Support Team
Unified Automation Support Team
-
- Jr. Member
- Posts: 3
- Joined: 22 Jun 2018, 10:06
Re: Numeric NodeId vs. String NodeId
In which specification is written down, that I have to use StringIds (and I am not allowed to use NumercIds) for dynamic Nodes and numeric NodeIds for static? I only found the line saying that IDs are not allowed to change for static Nodes.Numeric NodeIds are used for static nodes that do not change e.g. for type systems, generated code or nodes baked into a firmware of an embedded device. The UaModeler is using numeric NodeIds for the generated code.
String NodeIds are used for dynamic systems since it is normally easy to recalculate the same NodeId at every server start based on names in the hierarchy.
GUID NodeIds are used if it must be ensured that they are globally unique.
for GUID:
Is there a way to copy from uint32 and uint16 to the GUID NodeId and not with the UAString. This is one more unneeded step. (I am using the newest UA SDK Cpp)
Thanks,
Fabian
- Support Team
- Hero Member
- Posts: 3070
- Joined: 18 Mar 2011, 15:09
Re: Numeric NodeId vs. String NodeId
The above text are recommendations and guidelines, not rules.
OPC UA Part 3 (5.2.2 NodeId) states:
A Server shall persist the NodeId of a Node, that is, it shall not generate new NodeIds when rebooting.
This implies that you need to be able to use the exact same NodeId during the lifetime of a Node in a system. If you can ensure this for numeric identifiers in dynamic systems, you can use numeric identifiers.
OPC UA Part 3 (5.2.2 NodeId) states:
A Server shall persist the NodeId of a Node, that is, it shall not generate new NodeIds when rebooting.
This implies that you need to be able to use the exact same NodeId during the lifetime of a Node in a system. If you can ensure this for numeric identifiers in dynamic systems, you can use numeric identifiers.
Best regards
Unified Automation Support Team
Unified Automation Support Team
-
- Jr. Member
- Posts: 1
- Joined: 16 Nov 2021, 11:04
Re: Numeric NodeId vs. String NodeId
Hi support Team,
I have a question with regards zanetta's post about USE_MEMORY_OPTIMIZED_PARENT_POINTER
in post https://forum.unified-automation.com/viewtopic.php?p=4096#p4096 above
We are experiencing similar problems in our embedded target using C++ SDK 1.5.6.361:
- The creation of 2000 alarms nodes of type derived from OpcUa::OffNormalAlarmType takes 10x longer than required to create 2000 variable nodes of type derived from OpcUa::AnalogItemType.
- When we increase the number of alarm nodes to 4000, the time required to create them far exceeds 5 minutes, and the target experiences memory fragmentation issues which render it unusable.
Inspecting SDK sources, I find two defines
In src/uaserver/uaservercpp/coremodule/opcua_basevariabletype.cpp
#define USE_MEMORY_OPTIMIZED_PARENT_POINTER OPCUA_CONFIG_YES
And in src/uaserver/uaservercpp/coremodule/opcua_baseobjecttype.cpp
#define USE_MEMORY_OPTIMIZED_PARENT_POINTER OPCUA_CONFIG_NO
Setting to OPCUA_CONFIG_YES in opcua_baseobjecttype.cpp breaks build, because the code now uses a pointer to parent node which, as opposed to BaseVariableType, is not an argument in ctor.
I wonder:
- Do newer versions of the SDK enable changing this setting?
- If enabled, might it make our memory fragmentation problem less severe?
Regards,
Daniel Barral
I have a question with regards zanetta's post about USE_MEMORY_OPTIMIZED_PARENT_POINTER
in post https://forum.unified-automation.com/viewtopic.php?p=4096#p4096 above
We are experiencing similar problems in our embedded target using C++ SDK 1.5.6.361:
- The creation of 2000 alarms nodes of type derived from OpcUa::OffNormalAlarmType takes 10x longer than required to create 2000 variable nodes of type derived from OpcUa::AnalogItemType.
- When we increase the number of alarm nodes to 4000, the time required to create them far exceeds 5 minutes, and the target experiences memory fragmentation issues which render it unusable.
Inspecting SDK sources, I find two defines
In src/uaserver/uaservercpp/coremodule/opcua_basevariabletype.cpp
#define USE_MEMORY_OPTIMIZED_PARENT_POINTER OPCUA_CONFIG_YES
And in src/uaserver/uaservercpp/coremodule/opcua_baseobjecttype.cpp
#define USE_MEMORY_OPTIMIZED_PARENT_POINTER OPCUA_CONFIG_NO
Setting to OPCUA_CONFIG_YES in opcua_baseobjecttype.cpp breaks build, because the code now uses a pointer to parent node which, as opposed to BaseVariableType, is not an argument in ctor.
I wonder:
- Do newer versions of the SDK enable changing this setting?
- If enabled, might it make our memory fragmentation problem less severe?
Regards,
Daniel Barral