所以我在一个名为Camelize
return strtr(ucwords(strtr($id, array('_' => ' ', '.' => '_ ', '\\' => '_ '))), array(' ' => ''));
这只是骆驼化的东西。
我有大约211k的记录,迭代一段时间循环,theese记录有一些我需要登记的单词,最长的单词可以是大约10个字符,容易peasy,但运行一些xhprof测试我得出结论,camelize不是一个好主意如果你需要速度。
XHProf与camelize :313,866,303微秒(~5分钟)
没有驼峰的XHProf :5599,811微秒(<1分钟)
此脚本的目的是将值设置为类属性。
一个属性可以是protected $myVar
,它是驼峰式的。
在我的构造函数中,我得到一个 下划线 属性(数组键)及其值(数组值)的数组。 my_var => foo
由于我们有camelized属性,我们需要将数组键转换为camelize,所以我们可以做类似的事情
$this->$camelizedProperty = $value
是的,我们本来可以使用下划线属性,所以我们不需要转换任何字符串,但这是一个旧的工作代码,现在它的属性大约是它的4倍,并且它被大量使用依赖关系,如果我们能找到一种加快camelizing的方法,那么现在不能将属性更改为下划线。
更新
使用microtime
的某些单独测试来进行实时比较,我最终得到了这个......
使用的方法:
strtr(ucwords(strtr($word, array('_' => ' ', '.' => '_ ', '\\' => '_ '))), array(' ' => ''))
lcfirst(str_replace(" ", "", ucwords(strtr($word, "_-", " "))))
str_replace(" ", "", ucwords(strtr($word, "_-", " ")))
每次迭代超过~100个字符串的平均结果:
正如@RST指出的那样,使用str_replace
比我的第一个方法快18%,但仍然很慢(如果我们有一个巨大的循环)
在20M记录中,使用xhprof,总结果为:
我们可以说lcfirst
不会减慢脚本速度(我认为这可能会导致一些较慢的时间)。
这个问题不是关于如何驯化,而是关于它如何影响我们脚本中的性能,这可能是使用它的最佳方式。
答案 0 :(得分:0)
那么,根据获得更快时间的重要性,您可以使用单个传递字符串迭代替换每个输入字符串的内置PHP函数调用。
2000万条记录的时间如下:
Method 1 time: 301.143823
Method 2 time: 54.648126
不可否认,这里的代码可能看起来有点丑陋,但显然会缩短时间。注意,使用5个输入字符串只需将运行数量变量($ runqty)设置为4百万,以便为每个方法获得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)。