cpp generate uuid via rand() and test speed which is 4 times+ faster than libuuid

发布时间 2023-07-20 06:40:30作者: Fred1987
// main.cpp
#include <algorithm>
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <cstdint>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <mutex>
#include <queue>
#include <sstream>
#include <thread>
#include <uuid/uuid.h>
#include <vector>

uint32_t rand32()
{
    return ((rand() & 0x3) << 30) | ((rand() & 0x7fff) << 15) | (rand() & 0x7fff);
}

void gen_uuid4(char uuid_value[37], size_t len)
{
    int n = snprintf(uuid_value, len, "%08x-%04x-%04x-%04x-%04x%08x",
                     rand32(),                       // Generates a 32-bit Hex number
                     rand32() & 0xffff,              // Generates a 16-bit Hex number
                     ((rand32() & 0x0fff) | 0x4000), // Generates a 16-bit Hex number of the form 4xxx (4 indicates the UUID version)
                     (rand32() & 0x3fff) + 0x8000,   // Generates a 16-bit Hex number in the range [0x8000, 0xbfff]
                     rand32() & 0xffff, rand32());   // Generates a 48-bit Hex number
    // return n >= 0 && n < len;             // Success only when snprintf result is a positive number and the provided buffer was large enough.
}

std::string get_time_now()
{
    std::chrono::time_point<std::chrono::high_resolution_clock> now = std::chrono::high_resolution_clock::now();
    time_t raw_time = std::chrono::high_resolution_clock::to_time_t(now);
    struct tm tm_info = *localtime(&raw_time);
    auto seconds = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch());
    auto mills = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
    auto micros = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch());
    auto nanos = std::chrono::duration_cast<std::chrono::nanoseconds>(now.time_since_epoch());
    std::stringstream ss;
    ss << std::put_time(&tm_info, "%Y%m%d%H%M%S")
       << "_"
       << std::setw(3) << std::setfill('0') << (mills.count() - seconds.count() * 1000)
       << std::setw(3) << std::setfill('0') << (micros.count() - mills.count() * 1000)
       << std::setw(3) << std::setfill('0') << (nanos.count() - micros.count() * 1000);
    return ss.str();
}

void write_file(const std::string &file_name)
{
    std::fstream w_file(file_name, std::ios::app);
    if (!w_file.is_open())
    {
        std::cout << "Create or open " << file_name << " failed!" << std::endl;
        return;
    }

    static std::uint64_t num = 0;
    static uint32_t loops = 0;
    std::stringstream ss;
    char uuid_value[37];
    srand(time(NULL));
    std::chrono::time_point<std::chrono::high_resolution_clock> _start_time, _end_time;
    while (1)
    {
        _start_time = std::chrono::high_resolution_clock::now();
        for (int i = 0; i < 1000000; i++)
        {
            gen_uuid4(uuid_value, sizeof(uuid_value));
            ss << ++num << "," << uuid_value << std::endl;
        }
        w_file << ss.str();
        _end_time = std::chrono::high_resolution_clock::now();
        ss = std::stringstream();
        if (!w_file.good())
        {
            std::cout << get_time_now() << ",write failed loops:" << loops << ",num:" << num << std::endl;
            break;
        }
        std::cout << get_time_now() << ",loops:" << ++loops << ",num:" << num << ",time cost:"
                  << std::chrono::duration_cast<std::chrono::seconds>(_end_time - _start_time).count() << " seconds,"
                  << std::chrono::duration_cast<std::chrono::milliseconds>(_end_time - _start_time).count() << " mills,"
                  << std::chrono::duration_cast<std::chrono::microseconds>(_end_time - _start_time).count() << " micros,"
                  << std::chrono::duration_cast<std::chrono::nanoseconds>(_end_time - _start_time).count() << " nanos!!!" << std::endl;
    }
    w_file.close();
    std::cout << get_time_now() << ",loops:" << loops << ",num:" << num << ",finished in " << __FUNCTION__ << std::endl;
}

void test_1_million_uuid_time_cost(const int &loops)
{
    char uuid_value[37];
    srand(time(NULL));
    std::chrono::time_point<std::chrono::high_resolution_clock> _start_time, _end_time;
    for (int i = 0; i < loops; i++)
    {
        _start_time = std::chrono::high_resolution_clock::now();
        for (int j = 0; j < 1000000; j++)
        {
            gen_uuid4(uuid_value, sizeof(uuid_value));
        }
        _end_time = std::chrono::high_resolution_clock::now();
        std::cout << get_time_now() << ",loops:" << i + 1 << ",time cost:"
                  << std::chrono::duration_cast<std::chrono::seconds>(_end_time - _start_time).count() << " seconds,"
                  << std::chrono::duration_cast<std::chrono::milliseconds>(_end_time - _start_time).count() << " mills,"
                  << std::chrono::duration_cast<std::chrono::microseconds>(_end_time - _start_time).count() << " micros,"
                  << std::chrono::duration_cast<std::chrono::nanoseconds>(_end_time - _start_time).count() << " nanos!!!" << std::endl;
    }
    std::cout << get_time_now() << ",loops:" << loops << ",thread id: " << std::this_thread::get_id() << ",finished in " << __FUNCTION__ << std::endl;
}

int main(int args, char **argv)
{
    write_file(argv[1]);
    //test_1_million_uuid_time_cost(atoi(argv[1]));
    std::cout << get_time_now() << ",thread id:" << std::this_thread::get_id() << ",in " << __FUNCTION__ << std::endl;
}

Compile

g++-12 -std=c++2a -I. *.cpp -o h1

  

Run

nohup ./h1 log.txt >>write.log |tail -f write.log