Speed up numeric sorting by 10x.
Convert strings to int, sort, then convert back to strings.
This commit is contained in:
parent
bcbe48b13f
commit
e258bcb3a7
@ -749,11 +749,11 @@ generic_string stringJoin(const std::vector<generic_string> &strings, const gene
|
||||
return joined;
|
||||
}
|
||||
|
||||
int stoi_CountEmptyLinesAsMinimum(const generic_string &input)
|
||||
int stoiStrict(const generic_string &input)
|
||||
{
|
||||
if (input.empty())
|
||||
{
|
||||
return INT_MIN;
|
||||
throw std::invalid_argument("Empty input.");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -778,14 +778,14 @@ int stoi_CountEmptyLinesAsMinimum(const generic_string &input)
|
||||
}
|
||||
}
|
||||
|
||||
bool allLinesAreNumericOrEmpty(const std::vector<generic_string> &lines)
|
||||
bool allLinesAreNumeric(const std::vector<generic_string> &lines)
|
||||
{
|
||||
const auto endit = lines.end();
|
||||
for (auto it = lines.begin(); it != endit; ++it)
|
||||
{
|
||||
try
|
||||
{
|
||||
stoi_CountEmptyLinesAsMinimum(*it);
|
||||
stoiStrict(*it);
|
||||
}
|
||||
catch (std::invalid_argument&)
|
||||
{
|
||||
@ -797,4 +797,50 @@ bool allLinesAreNumericOrEmpty(const std::vector<generic_string> &lines)
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<generic_string> lexicographicSort(std::vector<generic_string> input, bool isDescending)
|
||||
{
|
||||
std::sort(input.begin(), input.end(), [isDescending](generic_string a, generic_string b)
|
||||
{
|
||||
if (isDescending)
|
||||
{
|
||||
return a.compare(b) > 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return a.compare(b) < 0;
|
||||
}
|
||||
});
|
||||
return input;
|
||||
}
|
||||
|
||||
std::vector<generic_string> numericSort(std::vector<generic_string> input, bool isDescending)
|
||||
{
|
||||
// Pre-condition: all strings in "input" are convertible to int with stoiStrict.
|
||||
std::vector<int> inputAsInts;
|
||||
std::map<int, generic_string> intToString; // Cache for ints converted to strings.
|
||||
for (auto it = input.begin(); it != input.end(); ++it)
|
||||
{
|
||||
int converted = stoiStrict(*it);
|
||||
inputAsInts.push_back(converted);
|
||||
intToString[converted] = *it;
|
||||
}
|
||||
std::sort(inputAsInts.begin(), inputAsInts.end(), [isDescending](int a, int b)
|
||||
{
|
||||
if (isDescending)
|
||||
{
|
||||
return a > b;
|
||||
}
|
||||
else
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
});
|
||||
std::vector<generic_string> output;
|
||||
for (auto it = inputAsInts.begin(); it != inputAsInts.end(); ++it)
|
||||
{
|
||||
output.push_back(intToString[*it]);
|
||||
}
|
||||
return output;
|
||||
}
|
@ -190,7 +190,10 @@ generic_string stringToUpper(generic_string strToConvert);
|
||||
generic_string stringReplace(generic_string subject, const generic_string& search, const generic_string& replace);
|
||||
std::vector<generic_string> stringSplit(const generic_string& input, const generic_string &delimiter);
|
||||
generic_string stringJoin(const std::vector<generic_string> &strings, const generic_string &separator);
|
||||
int stoi_CountEmptyLinesAsMinimum(const generic_string &input);
|
||||
bool allLinesAreNumericOrEmpty(const std::vector<generic_string> &lines);
|
||||
int stoiStrict(const generic_string &input);
|
||||
bool allLinesAreNumeric(const std::vector<generic_string> &lines);
|
||||
|
||||
std::vector<generic_string> numericSort(std::vector<generic_string> input, bool isDescending);
|
||||
std::vector<generic_string> lexicographicSort(std::vector<generic_string> input, bool isDescending);
|
||||
|
||||
#endif //M30_IDE_COMMUN_H
|
||||
|
@ -2979,37 +2979,17 @@ void ScintillaEditView::sortLines(size_t fromLine, size_t toLine, bool isDescend
|
||||
}
|
||||
}
|
||||
assert(toLine - fromLine + 1 == splitText.size());
|
||||
const bool isNumericSort = allLinesAreNumericOrEmpty(splitText);
|
||||
std::sort(splitText.begin(), splitText.end(), [isDescending, isNumericSort](generic_string a, generic_string b)
|
||||
const bool isNumericSort = allLinesAreNumeric(splitText);
|
||||
std::vector<generic_string> sortedText;
|
||||
if (isNumericSort)
|
||||
{
|
||||
if (isDescending)
|
||||
{
|
||||
if (isNumericSort)
|
||||
{
|
||||
int numA = stoi_CountEmptyLinesAsMinimum(a);
|
||||
int numB = stoi_CountEmptyLinesAsMinimum(b);
|
||||
return numA > numB;
|
||||
}
|
||||
else
|
||||
{
|
||||
return a.compare(b) > 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isNumericSort)
|
||||
{
|
||||
int numA = stoi_CountEmptyLinesAsMinimum(a);
|
||||
int numB = stoi_CountEmptyLinesAsMinimum(b);
|
||||
return numA < numB;
|
||||
}
|
||||
else
|
||||
{
|
||||
return a.compare(b) < 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
const generic_string joined = stringJoin(splitText, getEOLString());
|
||||
sortedText = numericSort(splitText, isDescending);
|
||||
}
|
||||
else
|
||||
{
|
||||
sortedText = lexicographicSort(splitText, isDescending);
|
||||
}
|
||||
const generic_string joined = stringJoin(sortedText, getEOLString());
|
||||
if (sortAllLines)
|
||||
{
|
||||
replaceTarget(joined.c_str(), startPos, endPos);
|
||||
|
Loading…
Reference in New Issue
Block a user