Updates: Be sure to check for (amazing) updates below the original answer
Memory mapping files supported me well 1 :
#include <boost/iostreams/device/mapped_file.hpp> // for mmap #include <algorithm> // for std::find #include <iostream> // for std::cout #include <cstring> int main() { boost::iostreams::mapped_file mmap("input.txt", boost::iostreams::mapped_file::readonly); auto f = mmap.const_data(); auto l = f + mmap.size(); uintmax_t m_numLines = 0; while (f && f!=l) if ((f = static_cast<const char*>(memchr(f, '\n', lf)))) m_numLines++, f++; std::cout << "m_numLines = " << m_numLines << "\n"; }
It should be pretty fast.
Update
In case this helps you test this approach, use using mmap directly instead of using Boost: see it live on Coliru
#include <algorithm> #include <iostream> #include <cstring> // for mmap: #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> const char* map_file(const char* fname, size_t& length); int main() { size_t length; auto f = map_file("test.cpp", length); auto l = f + length; uintmax_t m_numLines = 0; while (f && f!=l) if ((f = static_cast<const char*>(memchr(f, '\n', lf)))) m_numLines++, f++; std::cout << "m_numLines = " << m_numLines << "\n"; } void handle_error(const char* msg) { perror(msg); exit(255); } const char* map_file(const char* fname, size_t& length) { int fd = open(fname, O_RDONLY); if (fd == -1) handle_error("open"); // obtain file size struct stat sb; if (fstat(fd, &sb) == -1) handle_error("fstat"); length = sb.st_size; const char* addr = static_cast<const char*>(mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0u)); if (addr == MAP_FAILED) handle_error("mmap"); // TODO close fd at some point in time, call munmap(...) return addr; }
Update
The last bit of performance I could squeeze out of this I found by looking at the source of GNU coreutils wc . To my surprise, using the following (greatly simplified) code adapted from wc is executed at approximately 84% of the time taken with the above memory file:
static uintmax_t wc(char const *fname) { static const auto BUFFER_SIZE = 16*1024; int fd = open(fname, O_RDONLY); if(fd == -1) handle_error("open"); posix_fadvise(fd, 0, 0, 1);
1 see, for example, a reference indicator here: How to quickly parse floats with spatial separation in C ++?