// Author: Pete Kirkham // string match benchmark - mmap io, naive match algorithm. #include #include #include #include #include #include size_t string_search (const char* pattern, size_t pattern_length, const char* string, size_t string_length) { const char first(pattern[0]); const size_t last_index(string_length - pattern_length); for (size_t index(0); index < last_index; ++index) { if (first == string[index]) { for (size_t j(1); ; ) { if (string[index + j] != pattern[j]) break; ++j; if (j == pattern_length) return index; } } } return string_length; } int main (int narg, char** argvp) { if (narg < 2) { std::cout << "The name of the input file is required." << std::endl; return 1; } // open the file int file(open(argvp[1], O_RDONLY)); if (!file) { std::cout << "failed to open " << argvp[1] << std::endl; return 2; } // find length struct stat file_stat; if (fstat(file, &file_stat)) { std::cout << "failed to stat " << argvp[1] << std::endl; return 2; } // pattern to find const char* pattern("GET /ongoing/When/"); size_t pattern_length(strlen(pattern)); // mmap file size_t file_length(file_stat.st_size); void* mfile(mmap(0, file_length, PROT_READ, MAP_PRIVATE, file, 0)); if (!mfile) { std::cout << "failed to mmap " << argvp[1] << std::endl; return 2; } const char* buf(reinterpret_cast(mfile)); size_t matches(0); // scan for matches directly for (size_t index(0); index < file_length; ++index) { index += string_search(pattern, pattern_length, buf + index, file_length - index); index += pattern_length; while (index < file_length) { char ch(buf[index]); if ((ch == '.') || (ch == '\n')) { break; } if (ch == ' ') { ++matches; break; } ++index; } } munmap(mfile, file_length); std::cout << "matches: " << matches << std::endl; return 0; }