I have method which takes two parameters one as string
and other as int
.
The string has to compare with more than 50 string and Once the match is found int value need to be mapped with hard coded string as Example below
EX:
string Compare_Method(std::string str, int val) {
if(str == "FIRST")
{
std::array<std::string, 3> real_value = {"Hello1","hai1","bye1"}
return real_value[val];
}
else if(str == "SECOND")
{
std::array<std::string, 4> real_value = {"Hello2","hai2","bye2"}
return real_value[val];
}
else if(str == "THIRD")
{
std::array<std::string, 5> real_value = {"Hello3","hai3","bye3"}
return real_value[val];
}
//----- 50+ else if
}
My approach is as above. What will be the efficient way
1.To compare more than 50 string.
2. create std::array for each if case
EDITED : std::array size is not fixed it can be 3,4,5 as edited above.
So, Use 'is' (identity) operator than '==' (equality) operator to speed up your heavy string comparison operations.
While comparing the two function, in a loop repeted 500'000'000 times, strcmp execute too much fast, about x750 times faster. The execution time of that function is 3.058s , while strcmp only 0.004s .
This would be my way of doing that. The data structure is created only once and the access times should be fast enough
#include <iostream>
#include <string>
#include <array>
#include <unordered_map>
std::string Compare_Method(const std::string& str, int val)
{
// or std::vector<std::string>
static std::unordered_map<std::string, std::array<std::string, 3>> map
{
{ "FIRST", { "Hello1", "hail1", "bye1" }},
{ "SECOND", { "Hello2", "hail2", "bye2" }},
{ "THIRD", { "Hello3", "hail3", "bye3" }},
// 50+ more
};
// maybe check if str is present in the map
return map[str][val];
}
int main()
{
std::cout << Compare_Method("SECOND", 1) << std::endl;
}
If std::unordered_map
isn't (fast) enough for you, you can come up with some sort of static optimal hash structure, since keys are known at compile time.
If those 50 strings are something you will be widely using throughout your program, string
comparisons will take a toll on performance. I'd suggest you to adapt them to an enum
.
enum Strings
{
FIRST,
SECOND,
THIRD,
…
…
}
You'll obviously need a method to convert string
to int
whenever you get one from the source (user input, file read, etc.). This should be as infrequent as possible since your system now works on enum values (which can be used as indices on STL containers as we see in the next step)
int GetEnumIndex(const std::string& str)
{
// here you can map all variants of the same string to the same number
if ("FIRST" == str || "first" == str) return 1;
…
}
Then, the comparison method can be based on the enum
instead of the string
:
std::string Compare_Method(const int& strIndex, int val)
{
static std::vector<std::vector<std::string>> stringArray
{
{ "Hello1", "hail1", "bye1" },
{ "Hello2", "hail2", "bye2", "aloha2" },
{ "Hello3", "hail3", "bye3", "aloha3", "tata3" },
…
};
return stringArray[strIndex][val];
}
With information provided by you, I tried various variations to find out best way to achieve objective. I am listing best one here. You can see other methods here.
You can compile it and run run.sh
to compare performance of all cases.
std::string Method6(const std::string &str, int val) {
static std::array<std::string, 5> NUMBERS{"FIRST", "SECOND", "THIRD",
"FOURTH", "FIFTH"};
static std::array<std::vector<std::string>, 5> VALUES{
std::vector<std::string>{"FIRST", "hai1", "bye1"},
std::vector<std::string>{"Hello1", "SECOND", "bye1"},
std::vector<std::string>{"Hello1", "hai1", "THIRD"},
std::vector<std::string>{"FOURTH", "hai1", "bye1"},
std::vector<std::string>{"Hello1", "FIFTH", "bye1"}};
for (int i = 0; i < NUMBERS.size(); ++i) {
if (NUMBERS[i] == str) {
return VALUES[i][val];
}
}
return "";
}
For simplicity I have been using NUMBERS
with length of 5 but you can use what ever length you want to.
VALUES
is std::array
of std::vector
so you can add any number if element to std::vector
.
output from github code.
Method1 880 Method2 851 Method3 7292 Method4 989 Method5 598 Method6 440
You output may be different based on you system and system load at the time of execution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With