我的算法中有一个非常密集的函数。
我想尽量让它尽可能高效。我不太在乎可读性或类似的东西。只是速度。
该功能的基础是采取一组卡片:
$card1, $card2, $card3, $card4, $card5, $card6, $card7
每张卡都是数值。
然后,我需要从上面的集合中删除一组值。
$ remove_values = array(1,4,3,8,12);
所以基本上,我需要做的是,如果$ card1到$ card7出现在Remove Values中,请将该卡设置为0.
我目前的职能:
foreach($remove_values as $value) {
if($value === $card1) {
$card1 = 0;
}
if($value === $card2) {
$card2 = 0;
}
if($value === $card3) {
$card3 = 0;
}
if($value === $card4) {
$card4 = 0;
}
if($value === $card5) {
$card5 = 0;
}
if($value === $card6) {
$card6 = 0;
}
if($value === $card7) {
$card7 = 0;
}
}
这很有效。但我想知道是否有更快的方法呢?调用php函数非常密集,所以我试图减少这些调用的数量。
由于我的算法不得不循环数百万条结果,我真的试图减少毫秒。
答案 0 :(得分:0)
请尝试使用功能in_array()
。
if(in_array($card1, $remove_values)) {
$card1 = 0;
}
if(in_array($card2, $remove_values)) {
$card2 = 0;
}
if(in_array($card3, $remove_values)) {
$card3 = 0;
}
if(in_array($card4, $remove_values)) {
$card4 = 0;
}
if(in_array($card5, $remove_values)) {
$card5 = 0;
}
if(in_array($card6, $remove_values)) {
$card6 = 0;
}
if(in_array($card7, $remove_values)) {
$card7 = 0;
}
答案 1 :(得分:0)
我不知道这可能与其他答案或你自己在速度方面的功能相比如何,但它可能有所帮助。
$cards=array(
'card1' => 1,
'card2' => 5,
'card3' => 6,
'card4' => 8,
'card5' => 10,
'card6' => 11,
'card7' => 12
);
$remove_values = array(1,4,3,8,12);
function callback( &$item, $key, $removals ){
if( in_array( $item, $removals ) ) $item=0;
}
$result=array_walk( $cards, 'callback', $remove_values );
if( $result ){
echo '<pre>Cards:',PHP_EOL,print_r( $cards, true ),'</pre>';
}
/* Will output */
Cards:
Array
(
[card1] => 0
[card2] => 5
[card3] => 6
[card4] => 0
[card5] => 10
[card6] => 11
[card7] => 0
)
答案 2 :(得分:0)
您可以在设置卡等于零后“中断”循环,因此您不会在此之后评估其余的情况。
您还可以尝试将卡值放入数组中,并在将它们设置为零时将其删除,这样当您处理卡片时,每次都会搜索较小的数组。如果您可以像C ++地图那样对值和卡进行排序,那么搜索的速度会更快。
答案 3 :(得分:0)
使用SplFixedArray会略微改善性能。
$remove_values = new SplFixedArray(15);
$remove_values[1] = true;
$remove_values[4] = true;
$remove_values[3] = true;
$remove_values[8] = true;
$remove_values[12] = true;
if ($remove_values[$card1]) $card1 = 0;
if ($remove_values[$card2]) $card2 = 0;
if ($remove_values[$card3]) $card3 = 0;
if ($remove_values[$card4]) $card4 = 0;
if ($remove_values[$card5]) $card5 = 0;
if ($remove_values[$card6]) $card6 = 0;
if ($remove_values[$card7]) $card7 = 0;
你说过要做百万次循环。如果removed_values没有改变,只改变了卡的值,你总是可以对remove值的数组进行一些预处理,这样就可以进一步提高速度。
这是速度性能比较(一百万次循环)
| Normal Array | SplFixedArray
Pre-Processing | 4.2 seconds | 1.2 seconds
Normal | 5 seconds | 4.2 seconds
答案 4 :(得分:0)
这里的优化(在我的kludgy IDEONE.com测试中)快了25%。 对 remove_values 使用关联数组,然后执行键查找 isset 。 如果isset为true,我们要删除该值为TRUE - 1(0)&amp; cardValue = 0,但如果isset为false,我们希望将值保持为FALSE - 1(-1)&amp; cardValue = cardValue。这只是一些小问题,可以保留或清零卡值,而不必进行任何条件跳转。
$remove_values = array();
/* USE ASSOC. ARRAY */
for ($x = 0; $x <= 20; $x++) {
$r = rand(2, 14);
$remove_values[$r] = $r;
}
$card1 = rand(2, 14);
$card2 = rand(2, 14);
$card3 = rand(2, 14);
$card4 = rand(2, 14);
$card5 = rand(2, 14);
$card6 = rand(2, 14);
$card7 = rand(2, 14);
// Testing code
//
$card1 = (isset($remove_values[$card1]) - 1) & $card1;
$card2 = (isset($remove_values[$card2]) - 1) & $card2;
$card3 = (isset($remove_values[$card3]) - 1) & $card3;
$card4 = (isset($remove_values[$card4]) - 1) & $card4;
$card5 = (isset($remove_values[$card5]) - 1) & $card5;
$card6 = (isset($remove_values[$card6]) - 1) & $card6;
$card7 = (isset($remove_values[$card7]) - 1) & $card7;
如果你想弄乱它或尝试其他版本http://ideone.com/DDyQ4a
,那么这就是IDEONE答案 5 :(得分:0)
我发现这是一个奇怪的挑战,所以我按照OP的说明运行了10,000次迭代并使用了计时器助手类。
<?php
class TimingHelper {
private $start;
public function __construct() {
$this->start = microtime(true);
}
public function start() {
$this->start = microtime(true);
}
public function segs() {
return microtime(true) - $this->start;
}
public function time() {
$segs = $this->segs();
$days = floor($segs / 86400);
$segs -= $days * 86400;
$hours = floor($segs / 3600);
$segs -= $hours * 3600;
$mins = floor($segs / 60);
$segs -= $mins * 60;
$microsegs = ($segs - floor($segs)) * 1000;
$segs = floor($segs);
return
(empty($days) ? "" : $days . "d ") .
(empty($hours) ? "" : $hours . "h ") .
(empty($mins) ? "" : $mins . "m ") .
$segs . "s " .
$microsegs . "ms";
}
}
$cards=array(
'card1' => 1,
'card2' => 5,
'card3' => 6,
'card4' => 8,
'card5' => 10,
'card6' => 11,
'card7' => 12
);
$remove_values = array(1,4,3,8,12);
function callback( &$item, $key, $removals ){
if( in_array( $item, $removals ) ) $item=0;
}
$th = new TimingHelper;
$results=array();
for( $i=0; $i < 10000; $i++ ){
$th->start();
$result=array_walk( $cards, 'callback', $remove_values );
$results[]=$th->time();
}
echo min( $results );
/* Outputs */
/*
-> 0s 0.0138282775879ms
*/
?>