草庐IT

php - String camelize 性能慢

coder 2024-04-21 原文

所以我将这段代码放在一个名为 Camelize 的静态方法中

return strtr(ucwords(strtr($id, array('_' => ' ', '.' => '_ ', '\\' => '_ '))), array(' ' => ''));

这只是 Camel 化的东西。

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

XHProf with camelize:313,866,303 微秒(~5 分钟)

  • 19,268,795 通电话
  • 包括。墙时间 228,658,500
  • ICpu:81.3%

没有 camelize 的 XHProf:55,099,811 微秒(<1>

此脚本的目的是为类属性设置值。

一个属性可以被 protected $myVar,这是驼峰式的。

在我的构造函数中,我获得了一组下划线 属性(数组键)及其值(数组值)。 my_var => foo

因为我们有驼峰化属性,我们需要将数组键转换为驼峰化,所以我们可以做类似的事情 $this->$camelizedProperty = $value

是的,我们本来可以使用下划线属性,所以我们不需要转换任何字符串,但这是一个旧的工作代码,现在拥有大约 4 倍的属性,并且它被很多人使用的依赖关系,所以如果我们能找到加速 Camel 化的方法,那么将属性更改为下划线现在不是一个选择。

更新

使用 microtime 进行一些单独的测试以获得实时比较,我最终得到了这个......

使用的方法:

  1. strtr(ucwords(strtr($word, array('_' => ' ', '.' => '_ ', '\\' => '_ '))), array(' ' => ''))
  2. lcfirst(str_replace("", "", ucwords(strtr($word, "_-", ""))))
  3. str_replace("", "", ucwords(strtr($word, "_-", "")))

每次迭代 ~100 个字符串的平均结果:

  1. 0.0011
  2. 0.0002
  3. 0.0002

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

在 20M 条记录下,使用 xhprof,总结果为:

  1. 313 秒(~5 分钟)
  2. 152 秒(~2.5 分钟)
  3. 158 秒(~2.5 分钟)

我们可以说 lcfirst 不会减慢脚本速度(我认为这可能会导致一些时间变慢)。

这个问题不是关于如何驼峰化,而是关于它如何影响我们脚本的性能,以及哪种可能是使用它的最佳方式。

最佳答案

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

2000万条记录时间如下:

Method 1 time: 301.143823 
Method 2 time: 54.648126

不可否认,这里的代码可能看起来有些丑陋,但显然会缩短时间。请注意,对于 5 个输入字符串,只需将运行数量变量 ($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";

注意:如果您不希望第一个字母大写,则只需将 ucnext 变量初始化为 false(而不是如图所示的 true)。

关于php - String camelize 性能慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37071438/

有关php - String camelize 性能慢的更多相关文章

  1. Ruby 的数字方法性能 - 2

    我正在使用Ruby解决一些ProjectEuler问题,特别是这里我要讨论的问题25(Fibonacci数列中包含1000位数字的第一项的索引是多少?)。起初,我使用的是Ruby2.2.3,我将问题编码为:number=3a=1b=2whileb.to_s.length但后来我发现2.4.2版本有一个名为digits的方法,这正是我需要的。我转换为代码:whileb.digits.length当我比较这两种方法时,digits慢得多。时间./025/problem025.rb0.13s用户0.02s系统80%cpu0.190总计./025/problem025.rb2.19s用户0.0

  2. ruby - Ruby 性能中的计时器 - 2

    我正在寻找一个用ruby​​演示计时器的在线示例,并发现了下面的代码。它按预期工作,但这个简单的程序使用30Mo内存(如Windows任务管理器中所示)和太多CPU有意义吗?非常感谢deftime_blockstart_time=Time.nowThread.new{yield}Time.now-start_timeenddefrepeat_every(seconds)whiletruedotime_spent=time_block{yield}#Tohandle-vesleepinteravalsleep(seconds-time_spent)iftime_spent

  3. ruby-on-rails - 如果条件与 &&,是否有任何性能提升 - 2

    如果用户是所有者,我有一个条件来检查说删除和文章。delete_articleifuser.owner?另一种方式是user.owner?&&delete_article选择它有什么好处还是它只是一种写作风格 最佳答案 性能不太可能成为该声明的问题。第一个要好得多-它更容易阅读。您future的自己和其他将开始编写代码的人会为此感谢您。 关于ruby-on-rails-如果条件与&&,是否有任何性能提升,我们在StackOverflow上找到一个类似的问题:

  4. ruby - 如何找到我的 Ruby 应用程序中的性能瓶颈? - 2

    我编写了一个Ruby应用程序,它可以解析来自不同格式html、xml和csv文件的源中的大量数据。我如何找出代码的哪些区域花费的时间最长?有没有关于如何提高Ruby应用程序性能的好资源?或者您是否有任何始终遵循的性能编码标准?例如,你总是用加入你的字符串吗?output=String.newoutput或者你会使用output="#{part_one}#{part_two}\n" 最佳答案 好吧,有一些众所周知的做法,例如字符串连接比“#{value}”慢得多,但是为了找出您的脚本在哪里消耗了大部分时间或比所需时间更多,您需要进行分

  5. STM32的HAL和LL库区别和性能对比 - 2

    LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L

  6. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  7. ruby - GC.disable 的任何性能缺点? - 2

    是否存在GC.disable会降低性能的情况?只要我使用的是真正的RAM而不是交换内存,就可以这样做吗?我正在使用MRIRuby2.0,据我所知,它是64位的,并且使用的是64位的Ubuntu:ruby2.0.0p0(2013-02-24revision39474)[x86_64-linux]Linux[redacted]3.2.0-43-generic#68-UbuntuSMPWedMay1503:33:33UTC2013x86_64x86_64x86_64GNU/Linux 最佳答案 GC.disable将禁用垃圾回收。像rub

  8. ruby-on-rails - Rails with angular 与 Rails pure(查看性能) - 2

    我尝试在Internet上搜索有关使用angularJS进入RubyonRails项目与RubyonRailspure的View性能的信息。我的问题是因为2个月前我开始使用纯AngularJS,现在我需要将AngularJS集成到一个新项目中,但需要展示使用带有RubyonRails的AngularJS呈现View的性能如何,并消除对RubyonRails的负担.例如:带Rails的Angular:使用RubyonRails获取数据(从数据库或GET请求),将信息发送到file.js.erb并使用AngularJS操作数据并显示带有解析数据的View。纯粹的Rails:(自然流程)使用

  9. ruby-on-rails - 在 Rails 3 应用程序中使用 require_dependency 对性能有何影响? - 2

    我觉得我理解require和require_dependency之间的区别(来自Howarerequire,require_dependencyandconstantsreloadingrelatedinRails?)。但是,我想知道如果我使用一些不同的方法(参见http://hemju.com/2010/09/22/rails-3-quicktip-autoload-lib-directory-including-all-subdirectories/和Bestwaytoloadmodule/classfromlibfolderinRails3?)来加载所有文件会发生什么,所以我们:

  10. arrays - Ruby 中的并行分配性能 - 2

    设置一个临时变量来交换数组中的两个元素似乎比使用并行赋值更有效。谁能帮忙解释下?require"benchmark"Benchmark.bmdo|b|b.reportdo40000000.times{array[1],array[2]=array[2],array[1]}endendBenchmark.bmdo|b|b.reportdo40000000.timesdot=array[1]array[1]=array[2]array[2]=tendendend结果:usersystemtotalreal4.4700000.0200004.490000(4.510368)usersyste

随机推荐