DEV Community

Discussion on: Performance des UUIDs

Collapse
utix profile image
Aurélien Lajoie

J'ai refait un module en C pour voir pour aller encore plus loin.
J'ai modifié le module pecl pour garder les tests et les signatures de fonction
Premier test, sans validation du uuid sur le constructeur, deuxième en gardant la validation, troisième la version custom de git:

ext-uuid => 2753 ms
ext-uuid_c => 3735 ms
custom => 4816 ms

Là où il y a le plus à gagner c'est sur le unparse.
Les deux fonctions modifiées

#define UUID_STRING_LEN 36
static inline int hex_to_bin(int x)
{
    switch (x) {
      case '0' ... '9': return x - '0';
      case 'a' ... 'f': return 10 + x - 'a';
      case 'A' ... 'F': return 10 + x - 'A';
      default:          return -1;
    }
}

static int __uuid_parse(const char *str, unsigned char uuid[16])
{
    int j = 0;
    for (int i = 0; i < UUID_STRING_LEN; i++) {
        if (i == 8 || i == 13 || i == 18 || i == 23) {
            if (str[i] != '-')
                return -1;
        } else if (!isxdigit(str[i])) {
            return -1;
        } else {
            int hi = hex_to_bin(str[i]);
            int lo = hex_to_bin(str[++i]);
            uuid[j++] = (hi << 4) | lo;
        }
    }
    return 0;
}

PHP_FUNCTION(uuid_parse)
{

    const char * uuid = NULL;
    size_t uuid_len = 0;
    uuid_t uuid_bin;



    if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &uuid, &uuid_len) == FAILURE) {                                    
        return;                                                                                                        
    }

    if (__uuid_parse(uuid, uuid_bin)) {                                                                                
        RETURN_FALSE;
    }                                                                                                                  

    RETURN_STRINGL((char *)uuid_bin, sizeof(uuid_t));                                                                  
}   

char const __str_digits_lower[36] = "0123456789abcdefghijklmnopqrstuvwxyz";                                            

static void __uuid_fmt(char buf[UUID_STRING_LEN + 1], const uuid_t uuid)                                               
{                                                                                                                      
    char *p = buf;                                                                                                     

    for (int i = 0; i < 16; i++) {                                                                                     
        if (i == 4 || i == 6 || i == 8 || i == 10) {                                                                   
            *p++ = '-'; 
        }
        *p++ = __str_digits_lower[uuid[i] >> 4];                                                                       
        *p++ = __str_digits_lower[uuid[i] & 15];                                                                       
    }   
    *p = '\0';                                                                                                         
}   

PHP_FUNCTION(uuid_unparse)
{

    const char * uuid = NULL;
    size_t uuid_len = 0;
    char uuid_txt[UUID_STRING_LEN + 1];



    if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &uuid, &uuid_len) == FAILURE) {
        return;
    }

    if (uuid_len != sizeof(uuid_t)) {
        RETURN_FALSE;
    }

    __uuid_fmt(uuid_txt, uuid);

    RETURN_STRINGL(uuid_txt, UUID_STRING_LEN);
}
Thread Thread
utix profile image
Aurélien Lajoie

Allez, améliorons directement util-linux spinics.net/lists/util-linux-ng/ms... sur le unparse ça divise par 10 le temps

Thread Thread
utix profile image
Aurélien Lajoie

Du coup en descendant les étages on finit par arriver à l'assembleur et aux instructions SIMD

stackoverflow.com/questions/538237...

Thread Thread
fredbouchery profile image
Frédéric Bouchery Author

Beau travail !

Thread Thread
utix profile image
Aurélien Lajoie