More than 40 years of software development, software architect, team leader, speaker and PHP evangelist. Currently working for CCMBenchmark Group company.
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);
}
More than 40 years of software development, software architect, team leader, speaker and PHP evangelist. Currently working for CCMBenchmark Group company.
Je viens d'ajouter le code en fin d'article ;)
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
Allez, améliorons directement util-linux spinics.net/lists/util-linux-ng/ms... sur le unparse ça divise par 10 le temps
Du coup en descendant les étages on finit par arriver à l'assembleur et aux instructions SIMD
stackoverflow.com/questions/538237...
Beau travail !
C'est mergé github.com/karelzak/util-linux/com...