Skip to content

Instantly share code, notes, and snippets.

@springmeyer
Created December 7, 2012 20:21
Show Gist options
  • Select an option

  • Save springmeyer/4236211 to your computer and use it in GitHub Desktop.

Select an option

Save springmeyer/4236211 to your computer and use it in GitHub Desktop.
benchmark of std::string trim
#include <iostream>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#define BOOST_CHRONO_HEADER_ONLY
#include <boost/chrono/process_cpu_clocks.hpp>
#include <boost/chrono.hpp>
#include <boost/thread/thread.hpp>
#include <boost/algorithm/string.hpp>
/*
clang++ -o faster-trim faster-trim.cpp `mapnik-config --cflags --libs` -L/opt/boost-51/lib -lboost_thread -lboost_system
*/
const int ITERATIONS = 1000000;
const int THREADS = 15;
const std::string test_case("\r -180,-90,180,90\n \t");
const std::string expected("-180,-90,180,90");
namespace test1 {
bool is_not_space(int ch)
{
if (ch == 32 || ch == 160 || ch == '\n' || ch == '\r' || ch == '\t') return false;
return true;
}
// trim from start
static inline std::string &ltrim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), is_not_space));
return s;
}
// trim from end
static inline std::string &rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(), is_not_space).base(), s.end());
return s;
}
// trim from both ends
static inline std::string &trim(std::string &s) {
return ltrim(rtrim(s));
}
void run() {
std::string test_string;
for (unsigned i=0;i<ITERATIONS;i++) {
test_string = test_case;
trim(test_string);
}
}
}
namespace test2 {
static inline std::string &trim(std::string &s) {
boost::trim(s);
return s;
}
void run() {
std::string test_string;
for (unsigned i=0;i<ITERATIONS;i++) {
test_string = test_case;
trim(test_string);
}
}
}
namespace test3 {
bool is_a_space(int ch)
{
return std::isspace(ch);//if (ch == 32 || ch == 160 || ch == '\n' || ch == '\r' || ch == '\t') return true;
//return false;
}
// trim from both ends
static inline std::string &trim(std::string &s) {
s.erase(std::remove_if(s.begin(), s.end(),
is_a_space), s.end());
return s;
}
void run() {
std::string test_string;
for (unsigned i=0;i<ITERATIONS;i++) {
test_string = test_case;
trim(test_string);
}
}
}
void benchmark(void test(),std::string const& name) {
using namespace boost::chrono;
typedef process_cpu_clock clock_type;
process_real_cpu_clock::time_point start = process_real_cpu_clock::now();
boost::thread_group threads;
for (unsigned i=0;i<THREADS;++i)
{
threads.create_thread(test);
}
threads.join_all();
clock_type::duration elapsed = process_real_cpu_clock::now() - start;
std::clog << boost::chrono::duration_cast<milliseconds>(elapsed)
<< " (" << boost::chrono::duration_cast<seconds>(elapsed) << ")"
<< " <-- " << name << "\n";
}
void validate(std::string & test(std::string &),std::string const& name) {
std::string test_string = test_case;
std::string result = test(test_string);
if (result != expected) {
std::clog << "invalid impl: '" << result << "' != '" << expected << "'\n";
}
}
int main() {
validate(&test1::trim,"right and left whitespace");
validate(&test2::trim,"boost::trim");
validate(&test3::trim,"isspace + all whitespace");
benchmark(&test1::run,"right and left whitespace");
benchmark(&test2::run,"boost::trim");
benchmark(&test3::run,"isspace + all whitespace");
return 0;
}

based on 8 core macbook pro and boost 1.51

$ ./faster-trim 
8073 milliseconds (8 seconds) <-- right and left whitespace
52240 milliseconds (52 seconds) <-- boost::trim
8286 milliseconds (8 seconds) <-- isspace + all whitespace
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment