Php 字符串camelize性能缓慢

Php 字符串camelize性能缓慢,php,Php,因此,我在一个名为Camelize return strtr(ucwords(strtr($id, array('_' => ' ', '.' => '_ ', '\\' => '_ '))), array(' ' => '')); 那只不过是把东西骆驼化了 我有大约211k条记录,在一个while循环中迭代,这些记录有一些单词我需要计算,最长的单词可以是大约10个字符,很简单,但是运行一些xhprof测试我得出结论,如果需要速度,计算不是一个好主意 XHProf和ca

因此,我在一个名为
Camelize

return strtr(ucwords(strtr($id, array('_' => ' ', '.' => '_ ', '\\' => '_ '))), array(' ' => ''));
那只不过是把东西骆驼化了

我有大约211k条记录,在一个while循环中迭代,这些记录有一些单词我需要计算,最长的单词可以是大约10个字符,很简单,但是运行一些xhprof测试我得出结论,如果需要速度,计算不是一个好主意

XHProf和camelize:313866303微秒(~5分钟)

  • 19268795次电话
  • 包括墙时间228658500
  • ICpu:81.3%
XHProf无camelize:55099811微秒(foo

因为我们有camelize属性,所以我们需要将数组键转换为camelize,这样我们就可以像
$this->$camelizedProperty=$value

是的,我们可以使用下划线属性,这样我们就不需要转换任何字符串,但这是一个旧的工作代码,现在它的属性是它的4倍左右,并且它被许多依赖项使用,因此如果我们能找到加快计算速度的方法,现在就不能选择将属性更改为下划线

更新

使用
microtime
的一些单独测试来获得实时比较,我最终得到了以下结果

使用的方法:

  • strtr(ucwords(strtr($word,array(''''=>'',''\'=>'','\\'=>'')),array('''=>''))
  • lcfirst(str\u替换(“,”),ucwords(strtr($word,“-”,”))
  • str\u replace(“,”,ucwords(strtr($word,“-”,”))
  • 每次迭代~100个字符串的平均结果:

  • 0.0011
  • 0.0002
  • 0.0002
  • 正如@RST所指出的,使用
    str_replace
    比我的第一个方法快18%,但仍然很慢(如果我们有一个巨大的循环)

    对于20M记录,使用xhprof,总结果如下:

  • 313秒(约5分钟)
  • 152秒(约2.5分钟)
  • 158秒(约2.5分钟)
  • 我们可以说,
    lcfirst
    不会减慢脚本的速度(我认为这可能会导致时间变慢)


    这个问题不是关于如何进行camellize,而是关于它如何影响脚本中的性能,以及使用它的最佳方式。

    好吧,根据获得更快时间的重要性,您可以将内置PHP函数调用替换为每个输入字符串的单次传递字符串迭代

    2000万条记录的时间如下:

    Method 1 time: 301.143823 
    Method 2 time: 54.648126
    
    诚然,这里的代码看起来可能有点难看,但它显然会缩短时间。注意,对于5个输入字符串,只需将run-quantity变量($runqty)设置为400万,就可以为每个方法获得2000万个记录计时-请确保先注释掉循环中的echo语句

    示例代码

    <?php
    
    $input = array();
    $input['my_var'] = 'foo';
    $input['this.that'] = 'blah';
    $input['try\\me'] = 'strange';
    $input['some_var_here'] = 'value';
    $input['final_cut'] = 'fc99';
    
    set_time_limit(600);
    
    $runqty = 1;
    
    // Method 1
    $m1start = microtime(true);
    for ($runs = 0; $runs < $runqty; $runs++)
    {
      foreach ($input as $word => $val)
      {
        $out = strtr(ucwords(strtr($word, array('_' => ' ', '.' => '_ ', '\\' => '_ '))), array(' ' => ''));
        echo "in: $word out: $out<br>\n";
      }
    }
    $m1stop = microtime(true);
    $m1time = $m1stop - $m1start;
    echo "Method 1 time: " . sprintf("%0.6f",$m1time);
    echo "<br>\n";
    
    // Method 2
    $m2start = microtime(true);
    for ($runs = 0; $runs < $runqty; $runs++)
    {
      foreach ($input as $word => $val)
      {
        $i=0;
        $len = strlen($word);
        $ucnext = true;
        $out = '';
    
        while ( $i < $len )
        {
          $char = $word[$i++];
          if ( $char == '_' || $char == '.' || $char == '\\' )
          {
            $ucnext = true;
            if ( $char == '.' )
              $char ='_';
            else
              $char = '';
          }
          else
          {
            if ( $ucnext )
            {
              if ( $char >= 'a' && $char <= 'z' )
                $char = ucfirst($char);
              $ucnext = false;
            }
          }
    
          $out .= $char;
        }
        echo "in: $word out: $out<br>\n";
      }
    }
    $m2stop = microtime(true);
    $m2time = $m2stop - $m2start;
    echo "Method 2 time: " . sprintf("%0.6f",$m2time);
    echo "<br>\n";
    

    内联代码是什么意思?
    我的意思是不从另一个类调用静态方法,或者基本上不调用方法字符串,而不是调用任何camelize方法。你在应用它什么?如果它是数据库记录,为什么不将最终的表单缓存在数据库中?同样,只需使用静态列表映射最常见的属性名。你不可能有2000万个不同的属性名?你在这里具体做什么?为什么要尝试转储211k记录到对象中?您确定不应该后退一步,在某个地方解决实际问题吗?