Skip to content

Instantly share code, notes, and snippets.

@matthewaveryusa
Created January 28, 2016 20:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewaveryusa/8d7de93401de96021bfe to your computer and use it in GitHub Desktop.
Save matthewaveryusa/8d7de93401de96021bfe to your computer and use it in GitHub Desktop.
#include <algorithm>
#include <string>
#include <vector>
#include <cstring>
#include <string>
#include <fstream>
#include <streambuf>
#include <iostream>
#include <ctime>
// 5 statements
template <class InputIt, class ForwardIt, class BinOp>
void for_each_token(InputIt first, InputIt last,
ForwardIt s_first, ForwardIt s_last,
BinOp binary_op)
{
while (first != last) {
const auto pos = find_first_of(first, last, s_first, s_last);
binary_op(first, pos);
if (pos == last) break;
first = next(pos);
}
}
// 2 statements
std::pair<size_t, size_t> DoTristansWay(std::string str)
{
size_t count = 0;
size_t max_len = 0;
constexpr char delims[] = " \n\t\r\f";
for_each_token(str.cbegin(), str.cend(),
delims, delims + sizeof(delims),
[&count,&max_len] (std::string::const_iterator first, std::string::const_iterator second) {
if (first != second)
max_len = std::max(max_len, (size_t) std::distance(first, second));
++count;
});
return {count,max_len};
}
// 5 statements
template <class InputIt, class ForwardIt, class BinOp>
void for_each_token2(InputIt first, InputIt last,
ForwardIt s_first, ForwardIt s_last,
BinOp binary_op)
{
auto max_char = std::max_element(s_first, s_last);
auto min_char = std::min_element(s_first, s_last);
while (first != last) {
auto pos = first;
while(*pos < *min_char || *pos > *max_char) ++pos;
pos = find_first_of(pos, last, s_first, s_last);
binary_op(first, pos);
if (pos == last) break;
first = next(pos);
}
}
// 2 statements
std::pair<size_t, size_t> DoMattsWay(std::string str)
{
size_t count = 0;
size_t max_len = 0;
constexpr char delims[] = " \n\t\r\f";
for_each_token2(str.cbegin(), str.cend(),
delims, delims + sizeof(delims),
[&count,&max_len] (std::string::const_iterator first, std::string::const_iterator second) {
if (first != second)
max_len = std::max(max_len, (size_t) std::distance(first, second));
++count;
});
return {count,max_len};
}
static bool IsDelim( char tst )
{
const char* DELIMS = " \n\t\r\f";
do // Delimiter string cannot be empty, so don't check for it. Real code should assert on it.
{
if( tst == *DELIMS )
return true;
++DELIMS;
} while( *DELIMS );
return false;
}
std::pair<size_t,size_t> DoJoshsWay(std::string& str)
{
size_t count = 0;
size_t max_len = 0;
char* pMutableString = (char*) malloc( str.size()+1 );
strcpy( pMutableString, str.c_str() );
char* p = pMutableString;
// skip leading delimiters
while( *p && IsDelim(*p) )
++p;
while( *p )
{
// note start of token
char* pTok = p;
do// skip non-delimiters
{
++p;
} while( !IsDelim(*p) && *p );
// clobber trailing delimiter with null
*p = 0;
max_len = std::max(max_len, (size_t) std::distance(pTok, p));
++count;
do // skip null, and any subsequent trailing delimiters
{
++p;
} while( *p && IsDelim(*p) );
}
free(pMutableString);
return {count,max_len};
}
int main() {
std::ifstream t("sponza.obj");
std::string str((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
{
clock_t begin = clock();
for(int i = 0; i < 10; ++i) {
DoTristansWay(str);
}
clock_t end = clock();
std::cout << end - begin << std::endl;
}
{
clock_t begin = clock();
for(int i = 0; i < 10; ++i) {
DoMattsWay(str);
}
clock_t end = clock();
std::cout << end - begin << std::endl;
}
{
clock_t begin = clock();
for(int i = 0; i < 10; ++i) {
DoJoshsWay(str);
}
clock_t end = clock();
std::cout << end - begin << std::endl;
}
}
//mavery@bos-lp86w:~$ g++ -std=c++1y ~/main.cpp -O3 && ./a.out
//1003632
//741816
//4199091
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment