To convert an ASCII string to an integer value, you cannot get much faster than atoi does, but you can speed it up by implementing the conversion function that you use inline. The version below increases the pointer behind the scanned digits, therefore it does not correspond to the atoi semantics, but this should help increase the analyzer's efficiency, as shown below. (There is clearly no error checking, so add it if you need it.)
static inline int my_parsing_atoi(const char *&s) { if (s) { bool neg = false; int val = 0; if (*s == '-') { neg = true; ++s; } for (;isdigit(*s);++s) val = 10*val + (*s - '0'); return neg ? -val : val; } return 0; } const char *p = input_line; if (p) { p += strspn(p, " "); while (*p) { int value1 = my_parsing_atoi(p); p += strspn(p, " "); } }
Make sure you correctly profile your code so that you know that your routine is being computed, not bound to I / O. In most cases, you will be involved with I / O, and the suggestions below are ways to mitigate this.
If you use C or C ++ file reader routines such as fread or fstream , you should get buffered reads that should already be quite efficient, but you can try using basic OS calls like POSIX read to read files in large blocks at a time to speed up file reading performance. To be truly fantastic, you can read your file asynchronously while it is being processed, either using threads or aio_read . You can even use mmap , and this will delete some overhead for copying the data, but if the file is extremely large, you will need to manage the map so that you munmap parts of the file that was scanned, and mmap in the new part for scanning.
I compared my parsing procedure above and the OP procedure using code that looked like this:
clock_t before_real; clock_t after_real; struct tms before; struct tms after; std::vector<char *> numbers; make_numbers(numbers); before_real = times(&before); for (int i = 0; i < numbers.size(); ++i) { parse(numbers[i]); } after_real = times(&after); std::cout << "user: " << after.tms_utime - before.tms_utime << std::endl; std::cout << "real: " << after_real - before_real << std::endl;
The difference between real and user is that real is the wall clock time, and user is the actual time spent by the OS that starts the process (so that context switches are not taken into account during operation time).
In my tests, my work was almost twice as fast as the OP routine (compiled with g++ -O3 on a 64-bit Linux system).