`

再谈PHP中的str_repeat函数实现

阅读更多

前段时间讨论了在PHP中生成某多个某字符或字符串的字符串的问题,呵呵。这句话听起来太别扭了。举个例子就是,生成10个a的字符串就是aaaaaaaaaa。当然这里的a可以是ab或任何其他字符串。

 

在博客“生成固定长度的某字符的字符串 PHP ”中描述了一共5中方法。也对这五种方法的效率进行了比对,其中以PHP中自带的str_repeat函数效率最优,这也在意料和情理之中。

方法4,5都是对PHP本身的函数进行了组配以实现相同的功能,虽然没有str_repeat优秀,但是其效率还是好过了方法1,和方法2.

 

方法1,2是用PHP语言自己实现的逻辑,通过字符串的迭代拼接实现的,效率当然不能和PHP中的builtin方法相提并论。

 

今天看到了PHP中的str_repeat函数的实现,仔细一看,原来和自己实现的方法1中的思路是“异曲同工”啊。那PHP中的str_repeat究竟是怎么做的呢?核心逻辑代码如下:

 

    result_len = input_len * mult;
    result = (char *)safe_emalloc(input_len, mult, 1);
    
    /* Heavy optimization for situations where input string is 1 byte long */
    if (input_len == 1) { 
        memset(result, *(input_str), mult); 
    } else {
        char *s, *e, *ee; 
        int l=0; 
        memcpy(result, input_str, input_len);
        s = result;
        e = result + input_len;
        ee = result + result_len;

        while (e<ee) {
            l = (e-s) < (ee-e) ? (e-s) : (ee-e);
            memmove(e, s, l);
            e += l;
        }
    }

    result[result_len] = '\0';

首先计算了结果字符串的长度。并分配了对应的内存空间。

然后将input_str拷贝到分配内存空间的最开始,

然后迭代将已经拷贝的内容复制到剩余的内存空间。

从代码逻辑可以看出,复制的思路不是一份一份复制的,而是复制一份、两份、四份、八份......

直到填满所分配的内存空间,然后奖内存空间的最后一位赋值为'\0'。

 

初次看到这段代码时对以下代码逻辑有不解:

 

     while (e<ee) {
            l = (e-s) < (ee-e) ? (e-s) : (ee-e);
            memmove(e, s, l);
            e += l;
        }

所分配的内存空间一定是input_str的整数倍+1。因此如果每次只是向后移一倍原始字符串长度的话,只需要在剩余长度小于原始字符串长度时退出循环,然后在将最后一位赋值为'\0'。不就可以了吗?

 

如果你也是这么想的,那么你和我刚开始犯了同样的错误。

因为,原始字符串的复制不是一份一份地进行的。如果复制7份的话(即str_repeat("abc",7);),只需要复制4次(包括第一次)。

而且最后一次复制之前剩余的未赋值的内存空间为原始字符串长度的3倍+1,即3*3+1。只需要将"abcabcabcabc"字符串中的前10个字符进行复制。这样,result_str最后一个字符必定是原始字符串的第一个字符,'a'。这个‘a’本来就是不要的。

 

索性直接:

result[result_len] = '\0';

其实就是最后字符串中那个不需要的'a'替换为字符串的结束符'\0'。

 

这样str_repeat函数就完成了。

 

****************************************************************

此外:

博客“生成固定长度的某字符的字符串 PHP ”中的方法1,虽然思想上和str_repeat一致,但是采用了字符串拼接方式,而且每次拼接都要产生新的字符串,对内存空间也是极大的浪费,如下示例:

 

如果要生成8个‘a’的字符串,首先会生成'aa',然后是‘aaaa’,然后是‘aaaaaaaa’。循环次数和str_repeat一致,但是中间生成了'aa','aaaa'两个无用字符串,而且,目标字符串越长,则垃圾越多。而且,循环中采用字符串拼接方式,效率也不高。

 

 

而str_repeat则没有多余的无用空间的分配和释放操作。

分享到:
评论

相关推荐

    PHP中的str_repeat函数在JavaScript中的实现

    需要注意的是,尽管在这个例子中JavaScript中实现了一个与PHP中str_repeat()函数类似的函数,但它们在底层实现和性能上都存在差异。在使用JavaScript进行编程时,对性能影响的考虑是非常重要的,特别是当操作涉及...

    php str_pad 函数用法简介

    与 `str_repeat` 函数不同,`str_pad` 不仅仅重复一个字符,而是将一个字符串填充到特定长度,而 `str_repeat` 只是简单地重复一个字符串。 `str_pad` 函数的语法如下: ```php str_pad(string, length, pad_...

    php中ob_flush函数和flush函数用法分析

    本文实例分析了php中ob_flush函数和flush函数用法。分享给大家供大家参考。具体如下: ... echo str_repeat('m0sh1' ,1000); for($i=0;$i&lt;4&gt;'; ob_flush(); flush(); sleep(1); } ?&gt; &lt;?

    php2go:使用Golang来实现PHP的常见内置函数

    PHP2Go 使用Golang来实现PHP的通用内置函数。 已经实现了约140多种功能。...str_repeat () strstr () strtr () str_shuffle () trim () ltrim () rtrim () explode () strtoupper () strtolower () chr () ord () nl2

    php常用函数集合

    - **功能**:该函数用于对字符串中的特殊字符进行转义,类似于C语言中的转义处理。 - **示例**: ```php echo addcslashes("Hello\nWorld", "\n"); // 输出: Hello\012World ``` ##### 2. `addslashes` – 使用...

    PHP通过内置函数memory_get_usage()猎取内存用法状况_.docx

    `str_repeat()`函数的使用是为了模拟内存消耗。`unset()`函数用来删除变量,从而释放内存。在实际应用中,类似地,当不再需要数据库查询结果时,可以使用`mysql_free_result()`来释放内存。 除了`memory_get_usage...

    php常用函数及用法简介

    - **功能**:用回调函数过滤数组中的元素。 - **示例**: ```php $arr = array(1, 2, 3, 4, 5); print_r(array_filter($arr, function ($value) { return $value % 2 == 0; })); // 输出: Array ( [1] =&gt; 2 [3...

    PHP常用函数有哪些.docx

    在PHP编程语言中,函数是实现特定功能的代码块,它们极大地丰富了PHP的功能并提高了开发效率。以下是一些PHP中常用的函数,涵盖了数学运算、字符串处理、数组操作等多个方面: 1. **数学函数** - `abs()`:计算一...

    PHP常用函数大全.doc

    在PHP中,字符串函数是非常重要的组成部分,用于处理文本数据。本文档将详细介绍部分重要的字符串处理函数及其用途。 #### 1. `addcslashes` - **功能**: 使用反斜线转义字符串中的特殊字符。 - **示例**: `...

    PHP常用函数总结

    在PHP开发中,熟练掌握并运用各种内置函数对于提高代码效率、增强程序功能至关重要。本文将详细介绍部分常用的PHP函数,特别是数学类函数和字符串处理函数。 #### 数学函数 数学函数是PHP中最基本且重要的函数之一...

    最全PHP常用函数解析

    最后,`str_ireplace()`是不区分大小写的`str_replace()`版本,`str_pad()`填充字符串使其达到指定长度,`str_repeat()`重复字符串,`str_replace()`用于替换字符串中的部分或全部内容,`strstr()`查找字符串中的子...

    php函数解析

    **功能**:此函数会像C语言一样使用反斜线(\)来转义字符串`$str`中的字符。`$charlist`参数定义了哪些字符应该被转义。 **示例**: ```php echo addcslashes("Hello, world!", "o"); // 输出: Hell\\o\\, w\\orl\\...

    PHP常用函数解析

    在PHP编程语言中,函数是实现特定功能的代码块,它们可以被重复使用,从而提高代码的可读性和效率。本篇文章将详细解析PHP中的一些常用函数,这些函数涵盖了字符串处理、加密、格式化和类型转换等多个方面。 1. **...

    采用PHP函数memory_get_usage获取PHP内存清耗量的方法

    一,函数原型 int memory_get_usage ([ bool... $var = str_repeat(“liuhui”, 10000); echo memory_get_usage(); unset($var); echo memory_get_usage(); ?&gt; 分别输出:62328 122504 62416 说明:memory_get_usage

    PHP常用函数大全

    43. **str_replace**: 替换字符串中的指定子串,是文本处理中最常用的函数之一,用于数据清洗或格式转换。 44. **str_rot13**: 执行rot13变换,一种简单的字母替换加密,将字母旋转13位,常用于隐藏论坛或新闻组中...

    php常用函数[总结].pdf

    在PHP编程语言中,函数是实现特定功能的代码块,可以重复使用,极大地增强了代码的复用性和可读性。以下是一些PHP中常用的字符串处理函数的详细说明: 1. `addcslashes()`:此函数用于在指定字符前添加反斜杠,用于...

Global site tag (gtag.js) - Google Analytics