Skip to content

Instantly share code, notes, and snippets.

@bwedding
Last active April 28, 2024 22:12
Show Gist options
  • Save bwedding/f21a12e67c6bbfdeb56def63967fa502 to your computer and use it in GitHub Desktop.
Save bwedding/f21a12e67c6bbfdeb56def63967fa502 to your computer and use it in GitHub Desktop.
Compare hand-rolled strrev vs std::reverse
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <chrono>
#include <random>
#include <ranges>
#include <algorithm>
#include <string_view>
using namespace std::chrono;
class ExecutionTimer
{
public:
// Use the best steady clock available
using Clock = std::conditional_t<high_resolution_clock::is_steady,
high_resolution_clock,
steady_clock>;
ExecutionTimer() = default;
inline ~ExecutionTimer()
{
std::string units = " microSeconds";
// Determine whether to print uSecs or mSecs or Secs
double count = duration_cast<microseconds>(Clock::now() - mStart).count();
if (count > 1000)
{
// Convert to milliseconds
units = " milliSeconds";
count /= 1000.0f;
if (count > 1000)
{
// Convert to seconds
units = " Seconds";
count /= 1000.0f;
}
}
std::cout
<< "Elapsed: " << count << units.data() << std::endl;
}
private:
Clock::time_point mStart = Clock::now();
};
std::string generateRandomString(size_t length)
{
// Define a set of characters to choose from (alphanumeric and some special characters)
const std::string charSet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
// Use a random device and a Mersenne Twister for random number generation
std::random_device rd;
std::mt19937 generator(rd());
// Create a uniform distribution to select random characters from charSet
std::uniform_int_distribution<> dist(0, charSet.length() - 1);
// Create the random string
std::string randomString;
for (size_t i = 0; i < length; ++i) {
randomString += charSet[dist(generator)];
}
return randomString;
}
char* _strrev(char* str)
{
char* p1, * p2;
if (!str || !*str)
return str;
for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
{
*p1 ^= *p2;
*p2 ^= *p1;
*p1 ^= *p2;
}
return str;
}
std::string reverseString(const std::string& str)
{
std::string result;
for (auto i = str.size() & ~1; i--; result += str[i ^ 1])
;
return result;
}
std::string reverseStringView(const std::string& str)
{
std::string result;
for (const auto chunk : str | std::ranges::views::chunk(2)
| std::ranges::views::reverse)
result += std::string_view(chunk);
return result;
}
std::string reverseStringView2(const std::string& str)
{
auto result = str
| std::views::chunk(2)
| std::views::reverse
| std::views::join
| std::ranges::to<std::string>();
return result;
}
int main(int argc, char* argv[])
{
std::random_device rd;
std::mt19937 generator(rd());
std::uniform_int_distribution<> lengthDist(25, 256);
{
std::cout << "Testing _strrev" << std::endl;
ExecutionTimer timer;
for (int i = 0; i < 1000000; ++i)
{
size_t randomLength = lengthDist(generator);
std::string randomString = generateRandomString(randomLength);
std::string reversedString = randomString;
_strrev((char*)reversedString.c_str());
}
}
{
std::cout << "Testing std::reverse" << std::endl;
ExecutionTimer timer;
for (int i = 0; i < 1000000; ++i)
{
size_t randomLength = lengthDist(generator);
std::string randomString = generateRandomString(randomLength);
std::string reversedString = randomString;
std::reverse(reversedString.begin(), reversedString.end());
}
}
{
std::cout << "Testing reverseString" << std::endl;
ExecutionTimer timer;
for (int i = 0; i < 1000000; ++i)
{
size_t randomLength = lengthDist(generator);
std::string randomString = generateRandomString(randomLength);
std::string reversedString = reverseString(randomString);
}
}
{
std::cout << "Testing reverseStringView" << std::endl;
ExecutionTimer timer;
for (int i = 0; i < 1000000; ++i)
{
size_t randomLength = lengthDist(generator);
std::string randomString = generateRandomString(randomLength);
std::string reversedString = reverseStringView(randomString);
}
}
{
std::cout << "Testing reverseStringView2" << std::endl;
ExecutionTimer timer;
for (int i = 0; i < 1000000; ++i)
{
size_t randomLength = lengthDist(generator);
std::string randomString = generateRandomString(randomLength);
std::string reversedString = reverseStringView(randomString);
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment