Compare commits

..

2 Commits

Author SHA1 Message Date
Frederik Hertzum 92e99a5874 Reduced memory usage by 50%
All checks were successful
/ Build-Stuff (push) Successful in 5s
2024-02-26 00:02:04 +01:00
Frederik Hertzum 23e5b02052 add notes about templating 2024-02-26 00:00:17 +01:00
2 changed files with 21 additions and 16 deletions

View File

@ -11,11 +11,11 @@ memory, to serve as a buffer for storing results.
1. Make benchmarks. 1. Make benchmarks.
2. Introduce more tests. 2. Introduce more tests.
2.1. Tests with pre, post and infix strings shared between the strings 2.1 Tests with pre, post and infix strings shared between the strings
2.2 Tests where the length of the strings are combinations of odd and 2.2 Tests where the length of the strings are combinations of odd and
even. even.
3. Reduce the size of the buffer. When this was done with the old version, 3. ~~Reduce the size of the buffer. When this was done with the old version,
performance was increased 100%. performance was increased 100%.~~
4. Look into SIMD instructions 4. Look into SIMD instructions
5. Look into parallelism. 5. Look into parallelism.
6. Templating the code 6. Templating the code
@ -36,3 +36,9 @@ longer string in the middle and then calculating the two parts sperately.
If that can be done, it should be easy to turn on the threads and make run this If that can be done, it should be easy to turn on the threads and make run this
on all the cores. on all the cores.
## Templating the code
There's nothing in the code that's specific to `std::string`, and there's no
real reason for keeping it restricted to `std::string`. Making this a template
should be trivial.

View File

@ -16,26 +16,25 @@ auto levenshtein_distance(std::string_view const& a, std::string_view const& b)
if (i != 0) return levenshtein_distance(a.substr(0, a.size() - i), b.substr(0, b.size() - i)); if (i != 0) return levenshtein_distance(a.substr(0, a.size() - i), b.substr(0, b.size() - i));
auto const buffer_length = a.size() + 1; auto const buffer_length = a.size() + 1;
auto buffers = new unsigned int[buffer_length * 2]; auto buffer = new unsigned int[buffer_length];
unsigned int * buffer[2] = {buffers, buffers + buffer_length}; std::iota(buffer, buffer + buffer_length, 0);
std::iota(buffer[0], buffer[1], 0);
std::fill(buffer[1], buffer[1] + buffer_length, 0);
for (auto i = 0u; i < b.size(); ++i) for (auto i = 0u; i < b.size(); ++i)
{ {
buffer[1][0] = i + 1; buffer[0] = i;
auto temp = i;
for (auto j = 0u; j < a.size(); ++j) for (auto j = 0u; j < a.size(); ++j)
{ {
buffer[1][j + 1] = std::min( temp = std::min(
buffer[0][j] + (a[j] == b[i] ? 0u : 1u), temp + (a[j] == b[i] ? 0u : 1u),
std::min(buffer[0][j + 1], buffer[1][j]) + 1u std::min(buffer[j + 1], buffer[j]) + 1u
); );
std::swap(buffer[j + 1], temp);
} }
std::swap(buffer[0], buffer[1]);
} }
auto cost = buffer[0][buffer_length - 1]; auto cost = buffer[buffer_length - 1];
delete [] buffers; delete [] buffer;
return cost; return cost;
} }