-
Notifications
You must be signed in to change notification settings - Fork 394
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reduce Optional_string usage #9232
Conversation
…into optional-string
@@ -15687,8 +15687,8 @@ void GetDXCoilIndex(EnergyPlusData &state, | |||
std::string const &DXCoilName, | |||
int &DXCoilIndex, | |||
bool &ErrorsFound, | |||
Optional_string_const ThisObjectType, | |||
Optional_bool_const SuppressWarning) | |||
std::string_view const ThisObjectType, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one is a good example of the easier changes. The argument is only used for errors, so the argument type is changed first.
} else { | ||
if (present(ThisObjectType)) { | ||
ShowSevereError(state, ThisObjectType + ", GetDXCoilIndex: DX Coil not found=" + DXCoilName); | ||
if (!ThisObjectType.empty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then the call to present
is changed to use the empty
method.
if (present(ThisObjectType)) { | ||
ShowSevereError(state, ThisObjectType + ", GetDXCoilIndex: DX Coil not found=" + DXCoilName); | ||
if (!ThisObjectType.empty()) { | ||
ShowSevereError(state, fmt::format("{}, GetDXCoilIndex: DX Coil not found={}", ThisObjectType, DXCoilName)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And finally the string handling is changed to something compatible with string_view
.
bool &ErrorsFound, | ||
Optional_string_const CheckName, | ||
Optional_int_const CheckNumber, | ||
Optional_string_const ObjectName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function was checking for uniqueness of an optional name or optional number based on the string in CheckType... which appears to always be one of two literal strings... so known at runtime. Replace that with two functions, one that checks for name and one that checks for number.
@@ -15720,7 +15719,7 @@ void GetDXCoilIndex(EnergyPlusData &state, | |||
} | |||
|
|||
std::string | |||
GetDXCoilName(EnergyPlusData &state, int &DXCoilIndex, bool &ErrorsFound, Optional_string_const ThisObjectType, Optional_bool_const SuppressWarning) | |||
GetDXCoilName(EnergyPlusData &state, int &DXCoilIndex, bool &ErrorsFound, std::string_view const ThisObjectType, bool const SuppressWarning) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Functions like this should not be necessary. This should just be state.dataDXCoils->DXCoils(DXCoilNum).Name
. The error checking and defaulting should not be necessary. You should not need to call a function to grab a field of an object whose index is known. I understand that this has nothing to do with this PR, but this is as good a place as any for me to hang this comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These functions should hopefully only get called during the input phase, but (a) good point and (b) I agree.
|
||
std::string GetDXCoilName( | ||
EnergyPlusData &state, int &DXCoilIndex, bool &ErrorsFound, Optional_string_const ThisObjectType, Optional_bool_const SuppressWarning); | ||
EnergyPlusData &state, int &DXCoilIndex, bool &ErrorsFound, std::string_view const ThisObjectType = {}, bool const SuppressWarning = false); | ||
|
||
Real64 GetCoilCapacity(EnergyPlusData &state, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing.
src/EnergyPlus/DataSurfaceColors.hh
Outdated
@@ -92,7 +92,7 @@ namespace DataSurfaceColors { | |||
std::string const &ColorType // for now, must be DXF | |||
); | |||
|
|||
void SetUpSchemeColors(EnergyPlusData &state, std::string const &SchemeName, Optional_string_const ColorType = _); | |||
void SetUpSchemeColors(EnergyPlusData &state, std::string const &SchemeName, std::string const &ColorType); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::string_view
@@ -1249,17 +1249,87 @@ int InputProcessor::getObjectItemNum(EnergyPlusData &state, | |||
return getIDFObjNum(state, ObjType, object_item_num); // if incoming input is idf, then return idf object order | |||
} | |||
|
|||
void InputProcessor::lowerRangeCheck(EnergyPlusData &state, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General comment about functions like these. You are passing 9 parameters to this function, 8 of which are only needed in the case of an error, which is presumably rare. This is MCCS (Make the Common Case Slow) 101. If you want to make a function out of the error message code itself, okay. But do the range check at the call site and only call that function if there is an actual error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went ahead and refactored the function that got split into this one and the other one below, but this only gets used in WeatherManager regardless of whether it was intended to be a general use function. That's another argument for it to go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. More important than this specific function, however, is the general lesson and pattern. One of the tenets of high-performance (or at least not terrible-performance) programming is "Make the Common Case Fast". Setting up parameters takes time. Don't take that time if those parameters will only be used infrequently, e.g., in the case of an error. Another example I see quite a bit of is functions that have many options that tweak their behavior in different ways. Yes, you are "reusing code" and that's good, but even good things can be taken too far. If those options are rarely used, then you're slowing down the more frequent instances of the function.
These "rules of thumb" are obvious once someone points them out to you. And they are invaluable. I learned this one in my second year graduate computer architecture class. MCCF is the rule of thumb for computer hardware design, and it applies to software just as well.
} | ||
} | ||
} | ||
|
||
void InputProcessor::rangeCheck(EnergyPlusData &state, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above. Understand that this is not part of this PR, but if I see something I'm going to say something.
Optional_string_const MaxString // Maximum indicator ('<', ',=') | ||
int const ScheduleIndex, // Which Day Schedule being tested | ||
Real64 const Minimum, // Minimum desired value | ||
bool const exclusiveMin, // Minimum indicator ('>', '>=') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
_, | ||
_, | ||
state.dataEnvrn->WeatherFileLocationTitle); | ||
state.dataInputProcessing->inputProcessor->lowerRangeCheck(state, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comment above about rangeCheck
function.
@jasondegraw the last PR just caused a conflict in one file. I'm happy to resolve if you want me to just let me know. |
@Myoldmopar Yes, that would be great if you could do that. This should be ready for review, when I last checked it was all good but it may have fallen behind develop a bit. |
Conflicts resolved, everything builds and passes fine. Carry on... |
@Myoldmopar I think we want to get this in now and get out of the way of some of the other work that is going on, who should do review of this PR? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great to have these cleaned up and some of the messiness that came along with these optionals gone.
This all looks OK to me. Nothing is jumping out as controversial, just a nice set of cleanup changes. I think this can merge right away if CI comes back green.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this looks awesome. I have no issues with this.
I'm not sure why Windows didn't come back yet, but I'm not going to hold it up. It was clean ahead of the merge from develop. Merging now, thanks @jasondegraw |
Pull request overview
Reduce the usage of the various forms of string optional arguments by about 50%. In many cases, the optional can be replaced with a
std::string_view
and the presence of the string can be checked with theempty
method. Most of the remaining cases either require a deeper refactor or are too tied up with other ongoing refactors that there's not a good way to get at changing just the optional argument. In a few situations, overloading has been used to shift run-time choices of behavior to compile-time choices of behavior, so there may be a (very) small performance benefit from this PR.Pull Request Author
Add to this list or remove from it as applicable. This is a simple templated set of guidelines.
Reviewer
This will not be exhaustively relevant to every PR.