Conversation
Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
|
@biodranik CCed |
|
Pulls: #562 |
|
@ahcorde is this good to go? |
|
I would like to see a performance measurement first. |
|
@jmachowinski do you have benchmark test? or anybody else does? |
|
Nope, and I see this is a problem, because we have no way of figuring out, if we improve stuff, or introduce regressions. @mjcarroll recently tried to improve things, and afterwards we figured out, the benchmark was pointless. |
| name += message_name; | ||
| name += '_'; | ||
|
|
||
| this->setName(name.c_str()); |
There was a problem hiding this comment.
setName accepts a std::string
| this->setName(name.c_str()); | |
| this->setName(name)); |
| std::string message_namespace(this->members_->message_namespace_); | ||
| std::string message_name(this->members_->message_name_); | ||
|
|
||
| if (!message_namespace.empty()) { | ||
| // Find and replace C namespace separator with C++, in case this is using C typesupport | ||
| message_namespace = std::regex_replace(message_namespace, std::regex("__"), "::"); | ||
| ss << message_namespace << "::"; | ||
| std::string::size_type pos = 0; | ||
| while ((pos = message_namespace.find("__", pos)) != std::string::npos) { | ||
| message_namespace.replace(pos, 2, "::"); | ||
| pos += 2; | ||
| } | ||
| } | ||
|
|
||
| std::string name; | ||
| name.reserve( | ||
| message_namespace.size() + 2 + 5 + message_name.size() + 1); // "::" + "dds_::" + "_" | ||
|
|
||
| if (!message_namespace.empty()) { | ||
| name += message_namespace; | ||
| name += "::"; | ||
| } |
There was a problem hiding this comment.
The code flow is a bit odd, why not declare name first, and do everything related to the namespace in one if, and keep the 'namespace string' scope local to the if ?
There was a problem hiding this comment.
Agree, the order should be
if (!message_namespace.empty()) {
std::string name;
name.reserve(...)
// ...
}
| message_namespace = std::regex_replace(message_namespace, std::regex("__"), "::"); | ||
| ss << message_namespace << "::"; | ||
| std::string::size_type pos = 0; | ||
| while ((pos = message_namespace.find("__", pos)) != std::string::npos) { |
There was a problem hiding this comment.
Perhaps comment that this is like this for performance reasons.
People might read this snippet and try to clean as you go and introduce a regex :)
There was a problem hiding this comment.
Any C++ developer should understand that:
- There's a huge overhead when using std::regex
- In-place/in-memory replacement is faster than any memory allocation + memory copying
There was a problem hiding this comment.
For this one there are good arguments for both code versions. If it is really only one time, the performance does not matter, and I would argue that maintainability and simplicity out weight performance. If it is in a hot code path the proposed version is clearly the winner. Anyway I am fine with both versions.
biodranik
left a comment
There was a problem hiding this comment.
This also looks like it will not improve the real performance of a system, as this constructor will only be called a few times during initialization of the serializers etc. And this is exactly my point, I think we are optimizing the wrong things here...
Even if this is not a performance-critical place, avoiding unnecessary, avoidable overhead everywhere in the code would be a good example to new contributors (and LLMs) to produce a better quality, faster code.
FOSS should not be slow and ugly, right?
| message_namespace = std::regex_replace(message_namespace, std::regex("__"), "::"); | ||
| ss << message_namespace << "::"; | ||
| std::string::size_type pos = 0; | ||
| while ((pos = message_namespace.find("__", pos)) != std::string::npos) { |
There was a problem hiding this comment.
Any C++ developer should understand that:
- There's a huge overhead when using std::regex
- In-place/in-memory replacement is faster than any memory allocation + memory copying
| std::string message_namespace(this->members_->message_namespace_); | ||
| std::string message_name(this->members_->message_name_); | ||
|
|
||
| if (!message_namespace.empty()) { | ||
| // Find and replace C namespace separator with C++, in case this is using C typesupport | ||
| message_namespace = std::regex_replace(message_namespace, std::regex("__"), "::"); | ||
| ss << message_namespace << "::"; | ||
| std::string::size_type pos = 0; | ||
| while ((pos = message_namespace.find("__", pos)) != std::string::npos) { | ||
| message_namespace.replace(pos, 2, "::"); | ||
| pos += 2; | ||
| } | ||
| } | ||
|
|
||
| std::string name; | ||
| name.reserve( | ||
| message_namespace.size() + 2 + 5 + message_name.size() + 1); // "::" + "dds_::" + "_" | ||
|
|
||
| if (!message_namespace.empty()) { | ||
| name += message_namespace; | ||
| name += "::"; | ||
| } |
There was a problem hiding this comment.
Agree, the order should be
if (!message_namespace.empty()) {
std::string name;
name.reserve(...)
// ...
}
I agree that this isn't going to have a huge impact, but getting this code cleaner won't hurt. I wouldn't encourage people to go out of their way to hunt for these things, but in this case it was uncovered when looking for other optimizations, so it seems low cost to just fix now. |
Description
The optimization follows biodranik's suggestion from the PR review, addressing the performance issue at its source.
Removed expensive operations:
Replaced with efficient plain string operations:
related to #561
Is this user-facing behavior change?
No,
Did you use Generative AI?
Yes, Claude Sonnet 4.6
Additional Information