Recently, I often need to match and replace strings. I usually used str_replace or preg_replace before. It is said that strtr is very efficient, so I compared it:
Copy code The code is as follows:
$i = 0;
$t = microtime(true);
for(;$i<1000;$i++)
{
$ str = strtr(md5($i), $p2);
}
var_dump(microtime(true)-$t); //0.085476875305176
$t = microtime(true);
for (;$i<2000;$i++)
{
$str = preg_replace($p, '', md5($i));
}
var_dump(microtime(true)-$ t); //0.09863805770874
The results show that strtr is about 15% more efficient than preg_replace.
I took advantage of the weekend to check the php source code of strtr:
Copy the code The code is as follows:
PHP_FUNCTION (strtr)
{
zval **str, **from, **to;
int ac = ZEND_NUM_ARGS();
//Parameter check (zend_get_parameters_ex function is defined in the zend_api.c file )
if (ac < 2 || ac > 3 || zend_get_parameters_ex(ac, &str, &from, &to) == FAILURE) {
WRONG_PARAM_COUNT;
}
// Parameter check
if (ac == 2 && Z_TYPE_PP(from) != IS_ARRAY) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The second argument is not an array.");
RETURN_FAL SE;
}
convert_to_string_ex(str);
/* shortcut for empty string */
//Macro Z_STRLEN_PP is defined in zend_operators.h
if (Z_STRLEN_PP(str) == 0) {
RETURN_EMPTY_STRING() ;
}
if (ac == 2) {
php_strtr_array(return_value, Z_STRVAL_PP(str), Z_STRLEN_PP(str), HASH_OF(*from));
} else {
convert_to_string_ex (from);
_to_string_ex(to);
Z_STRVAL_P(return_value),
MIN(Z_STRLEN_PP(from),
Let’s take a look at the php_strtr function first:
Copy the code
The code is as follows:
//trlen is the minimum length of the strings str_from and str_to
PHPAPI char *php_strtr(char *str, int len, char *str_from, char *str_to, int trlen)
{
int i;
unsigned char xlat[256]; //
if ((trlen < 1) || (len < 1)) {
return str;
}
//The subscript of xlat is equal to the value
for (i = 0; i < 256; xlat[i] = i, i++); Correspond. For example: from="ab",to="cd" will produce the correspondence 'a'=>'c', 'b'=>'d'.
The efficiency of this function can be improved, because if the characters that need to be replaced only occupy a small part of the entire string, most of the assignment operations are actually meaningless. In this case, it feels like judging first and then assigning values. I feel it will be more efficient. I will test it when I have time)
for (i = 0; i < len; i++) {
str[i] = xlat[(unsigned char) str[i]];
}
return str;
(Note: This operation outputs efcdeeefcd)
Look at php_strtr_array again:
Copy code
The code is as follows:
static void php_strtr_array(zval *return_value, char *str, int slen, HashTable *hash)
{
zval **entry;
char *string_key;
uint string_key_len;
zval **trans;
zval ctmp;
ulong num_key;
int minlen = 128*1024;
int maxlen = 0, pos, len, found;
char *key ;
HashPosition hpos;
smart_str result = {0};
HashTable tmp_hash;
//Copy the replacement array from hash to tmp_hash, and record the maximum and minimum length of the subscript string
zend_hash_init(&tmp_hash, 0, NULL, NULL, 0);
zend_hash_internal_pointer_reset_ex(hash, &hpos);
while (zend_hash_get_current_data_ex(hash, (void **)&entry, &hpos) == SUCCESS) {
switch (zend_hash_get_current_key_ex(hash, &string_key, &string_key_len, &num_key, 0, &hpos)) {
len = string_key_len-1;
through );
zend_hash_add(&tmp_hash, string_key, string_key_len, entry, sizeof(zval*), NULL); maxlen = len ;
minlen = len;
break; 🎜> case HASH_KEY_IS_LONG:
Z_LVAL(ctmp) = num_key;
len = Z_STRLEN(ctmp);
zend_hash_add(&tmp_hash, Z_STRVAL(ctmp), len+1, entry, sizeof(zval*), NULL);
zval_dtor(&ctmp);
if (len > maxlen }
if (len & lt; minlen) {
minlen = len;
}
Break;
}
Zend_hash_Move_Forward_ex (have, & hpos); emalloc(maxlen+1);
pos = 0;
//Loop matching starting from the first character of the string, pos records the current search position
while (pos < slen) {
}
found = 0; ','ab'=>'f'), it will replace ab with f first instead of replacing a with e first.
Quite high
if (zend_hash_find(&tmp_hash, key, len+1, (void**)&trans) == SUCCESS) {
int tlen;
zval tmp;
if ( Z_TYPE_PP(trans) != IS_STRING) {
(andtmp); 🎜> tlen = Z_STRLEN (tmp);
tlen = Z_STRLEN_PP(trans);
If (Z_TYPE_PP(trans ) != IS_STRING) {
smart_str_appendc(&result, str[pos++ ]);
}
}
efree(key);
zend_hash_destroy(&tmp_hash);
smart_str_0(&result);
RETVAL_STRINGL(result.c, result.len, 0) ;
}
http://www.bkjia.com/PHPjc/327900.html
www.bkjia.com
true
http: //www.bkjia.com/PHPjc/327900.html
TechArticle
Recently, we often need to match and replace strings. In the past, we usually used str_replace or preg_replace. It is said that strtr is very efficient. , so compare it: Copy the code code as...