Home > Back-end >  c 17 fast way for trans int to string with prefix '0'
c 17 fast way for trans int to string with prefix '0'

Time:06-28

I want to trans an int into string. I known under c 17, a better way is using std::to_string.

But now I want to fill the prefix with several '0'. For example, int i = 1, std::to_string(i) is '1', but I want the result is '00001'(total lenght is 5).

I know using sprintf or stringstream may achieve that. But which have a better performance or some other way?

CodePudding user response:

Yes, using snprintf or stringstream can both convert int to string with leading 0.

#include <chrono>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>

using std::chrono::duration_cast;
using std::chrono::high_resolution_clock;
using std::chrono::milliseconds;

std::string ss_to_string(int data) {
  std::stringstream ss;
  ss << std::setfill('0') << std::setw(5) << data;
  return ss.str();
}

std::string snprint_to_string(int data) {
  char buffer[6];
  snprintf(buffer, 6, "d", data);
  return buffer;
}

int main(int argc, char **argv) {

  auto t1 = high_resolution_clock::now();
  for (int i = 0; i < 100000; i  ) {
    ss_to_string(1);
  }
  auto t2 = high_resolution_clock::now();

  std::cout << "sstream version: "
            << duration_cast<milliseconds>(t2 - t1).count() << "ms\n";

  auto t3 = high_resolution_clock::now();
  for (int i = 0; i < 100000; i  ) {
    snprint_to_string(1);
  }
  auto t4 = high_resolution_clock::now();

  std::cout << "snprintf version: "
            << duration_cast<milliseconds>(t4 - t3).count() << "ms\n";
}

After measuring the snprintf version and stringstream version, it turns out that the snprintf implementation is more efficient.

sstream version: 60ms
snprintf version: 23ms

CodePudding user response:

If you know something about your domain and don't need to check for errors, nothing gets faster than rolling your own. For example if you know that your int is always in the range [0, 99'999], you could just:

std::string
convert(unsigned i)
{
    std::string r(5, '0');
    char* s = r.data()   4;
    do
    {
        *s-- = char(i % 10)   '0';
        i /= 10;
    } while (i > 0);
    return r;
}

General purpose libraries don't have the luxury of making such assumptions.

  • Related