几种常用的查找元素是否存在数组的方法,欢迎探讨,并提供更佳策略

amani11 2010-06-29 01:40:48
世界杯以来,可用分输了不少,爆冷的时候,我稳了,我想爆冷,南非那稳住了,心情极度郁闷,散个200分,希望能让我输到世界杯结束

上周做的一个测试,现在匆匆忙忙加了几行注释,发出来,因为皮厚,又戴着深度眼镜,也就不怕贻笑大方了

有蛮长一段时间,我都用foreach,in_array,array_search来查找数组中的元素,直觉觉得,系统提供的,都是及其优化后的方案,一直到之前遇到了一些问题。深刻体会到具体问题具体分析的概念

下面用了几种常用的判断方法,来检测数组中是否含有某一个元素,过程不说了,有兴趣的一看便知。

路过的朋友,若愿意测试,请把测试结果贴上来

也希望路过的朋友提供更优的方案,贴在下面,不胜感激

set_time_limit(0);

$arr = array();//测试数组

$arrLength = 5000;//测试数组长度

$arrType = 2;//1是1—1亿随机数字,2是8位字符串,3是32位字符串

$cycleTimes = 100;//测试次数,尽量避免偶然情况

$searchTimes = 50;//查找次数实际是50*2,50个能找到,50个找不到

$keywordArr = array();//要比对的元素,数组形式保存

$resultArr = array();//记录测试结果的数组

/**
* 构造数组元素
*
* @access public
* @param integer $arrType 元素类型
* @param bool $flag 为了构造差异元素
* @return string
*/
function creatItem($arrType = 1, $flag = true)
{
$item = '';
$seed = $flag ? rand(1, 50000000) : rand(50000001, 100000000);
switch($arrType)
{
case 1:
$item = $seed;
break;
case 2:
$item = sprintf('%X', crc32($seed));
break;
default:
$item = md5($seed);
}
return $item;
}

//测试数组赋值,同时保存$searchTimes个能找到的元素
for($i=0;$i<$arrLength;$i++)
{
$arr[] = creatItem($arrType, true);
if($i < $searchTimes)
{
$keywordArr[] = $arr[$i];
}
}

//构造$searchTimes个测试数组中没有的值
for($i=0;$i<$searchTimes;$i++)
{
$keywordArr[] = creatItem($arrType, false);
}

/*********************初始化结束*****************/

//每种方法测,都用到shuffle,所以这里顺便测试一下效率
$timeStart = gettimeofday();
for($i=0;$i<$cycleTimes;$i++)
{
shuffle($arr);
}
$resultArr['shuffle'] = gettimeofday();

//开始循环测试foreach
for($i=0;$i<$cycleTimes;$i++)
{
shuffle($arr);
foreach($keywordArr AS $v)
{
foreach($arr AS $value)
{
if($value == $v)
{
break;
}
}
}
}
$resultArr['foreach'] = gettimeofday();

//开始循环测试in_array
for($i=0;$i<$cycleTimes;$i++)
{
shuffle($arr);
foreach($keywordArr AS $v)
{
in_array($v, $arr);
}
}
$resultArr['in_array'] = gettimeofday();

//开始循环测试array_search
for($i=0;$i<$cycleTimes;$i++)
{
shuffle($arr);
foreach($keywordArr AS $v)
{
array_search($v, $arr);
}
}
$resultArr['array_search'] = gettimeofday();

//开始循环测试strpos
for($i=0;$i<$cycleTimes;$i++)
{
shuffle($arr);
$arraystring = ',' . implode(',', $arr) . ',';
foreach($keywordArr AS $v)
{
strpos($arraystring, ',' . $v . ',');
}
}
$resultArr['strpos'] = gettimeofday();

//开始循环测试array_key_exists
for($i=0;$i<$cycleTimes;$i++)
{
shuffle($arr);
$arr = array_flip($arr);
foreach($keywordArr AS $v)
{
array_key_exists($v, $arr);
}
}
$resultArr['array_key_exists'] = gettimeofday();

//开始循环测试isset($arr[$key])
for($i=0;$i<$cycleTimes;$i++)
{
shuffle($arr);
$arr = array_flip($arr);
foreach($keywordArr AS $v)
{
isset($arr[$v]);
}
}
$resultArr['isset_key'] = gettimeofday();

//打印结果
echo var_dump($arrLength, $arrType, $cycleTimes, $searchTimes) . '<br />';
foreach($resultArr AS $k => $v)
{
$time = ($v["usec"]-$timeStart["usec"])/1000000+$v["sec"]-$timeStart["sec"];
$time = round($time, 6)."秒";
echo $time . ' ' . $k . '<br />';
$timeStart = $v;
}
...全文
476 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
Dleno 2010-06-30
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 amani11 的回复:]
引用 14 楼 dingsongtao 的回复:
什么都不想说了.
我也和你一样,输光了,一盘都没赢过.冷门太多了.
现在只剩可怜的1分了.



哎~~~~~~~~~~~~~我分是还一些的,,但是输多赢少

不知道能转移些给你么?
[/Quote]


汗,你都才600多分了,算了,我不经常提问,分用的不多。
不过还是谢了!

徐老大多。
zmacro 2010-06-30
  • 打赏
  • 举报
回复
jf~~~~~~~~~~~~~~~~~~~~~~~~~~~
床上等您 2010-06-30
  • 打赏
  • 举报
回复
支持,我一直在用 

in_array()
array_search()

这两个方法的。

有时会使用 foreach
amani11 2010-06-30
  • 打赏
  • 举报
回复
分乃身外之物,无所谓,开心玩就好,不过没找到怎么送分,是不是等级低不让???
amani11 2010-06-30
  • 打赏
  • 举报
回复
哈哈哈~~~~~~~看到自己电脑差距了吧?

不过我比你更糟糕
LKK 2010-06-30
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 xuzuning 的回复:]

int(5000) int(2) int(100) int(50)
0.041007秒 shuffle
11.698075秒 foreach
8.002122秒 in_array
7.986511秒 array_search
2.050716秒 strpos
0.237464秒 array_key_exists
0.22903秒 isset_key
[/Quote]

int(5000) int(2) int(100) int(50)
0.132363秒 shuffle
23.241035秒 foreach
12.559198秒 in_array
12.540035秒 array_search
2.459958秒 strpos
0.393134秒 array_key_exists
0.396289秒 isset_key
总哈哈 2010-06-30
  • 打赏
  • 举报
回复
isset效率应该是可以的
amani11 2010-06-30
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 fxs_2008 的回复:]

up 这么说反转后isset效率最高?
[/Quote]

有测试有根据,,,,,不过也不是绝对的,比对次数较多的条件下,的确反转了效率高多了

越多越明显
fxs_2008 2010-06-30
  • 打赏
  • 举报
回复
up 这么说反转后isset效率最高?
amani11 2010-06-29
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 do_fork 的回复:]

array_flip性能很低, 每次判定都倒置一下数组是不能接受的,
还不如直接array_search或者in_array好,
如果判断值是否存在的操作很多,修改的操作不多,
那么维护一个value=>key的数组是很有必要的
[/Quote]

接受大部分意见,代码是有点问题

不过,有一点异议是,我这里之所以每次循环倒置key,value,是因为完成外层循环测试N次的目的

事实上,每一种查找,都加了外层循环N次,以便排除偶然情况,得到较为客观的结果

do_fork 2010-06-29
  • 打赏
  • 举报
回复
array_flip性能很低, 每次判定都倒置一下数组是不能接受的,
还不如直接array_search或者in_array好,
如果判断值是否存在的操作很多,修改的操作不多,
那么维护一个value=>key的数组是很有必要的
amani11 2010-06-29
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 dingsongtao 的回复:]
什么都不想说了.
我也和你一样,输光了,一盘都没赢过.冷门太多了.
现在只剩可怜的1分了.
[/Quote]


哎~~~~~~~~~~~~~我分是还一些的,,但是输多赢少

不知道能转移些给你么?
amani11 2010-06-29
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 xuzuning 的回复:]

int(5000) int(2) int(100) int(50)
0.041007秒 shuffle
11.698075秒 foreach
8.002122秒 in_array
7.986511秒 array_search
2.050716秒 strpos
0.237464秒 array_key_exists
0.22903秒 isset_key
[/Quote]
感谢

遗憾的是我上面代码,有些问题,不过也足以知道,机器比我的好,
Dleno 2010-06-29
  • 打赏
  • 举报
回复

什么都不想说了.
我也和你一样,输光了,一盘都没赢过.冷门太多了.
现在只剩可怜的1分了.
zhengbushou_520 2010-06-29
  • 打赏
  • 举报
回复
看不懂啊
amani11 2010-06-29
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 foolbirdflyfirst 的回复:]

我看php的方法都给你总结得差不多了,呵呵。
如果是我,碰到大数组的情况,一般会考虑牺牲空间,在$arr生成的时候构建一个索引表。其实和array_flip一样。
PHP code
...
//测试数组赋值,同时保存$searchTimes个能找到的元素
for($i=0;$i<$arrLength;$i++)
{
$arr[$i] = $rvalue = creatIte……
[/Quote]


虽然说跟array_flip原理差不多,但的确受到启发了……





另外,我贴的代码有些问题,不知道有人看出来没有……我本地测试的没有,为了整齐,我修改了一些变量,画蛇添足了
xuzuning 2010-06-29
  • 打赏
  • 举报
回复
int(5000) int(2) int(100) int(50)
0.041007秒 shuffle
11.698075秒 foreach
8.002122秒 in_array
7.986511秒 array_search
2.050716秒 strpos
0.237464秒 array_key_exists
0.22903秒 isset_key
foolbirdflyfirst 2010-06-29
  • 打赏
  • 举报
回复
我看php的方法都给你总结得差不多了,呵呵。
如果是我,碰到大数组的情况,一般会考虑牺牲空间,在$arr生成的时候构建一个索引表。其实和array_flip一样。
...
//测试数组赋值,同时保存$searchTimes个能找到的元素
for($i=0;$i<$arrLength;$i++)
{
$arr[$i] = $rvalue = creatItem($arrType, true);
$hash[$rvalue][] = $i;//...
if($i < $searchTimes)
{
$keywordArr[] = $arr[$i];
}
}
..

for($i=0;$i<$cycleTimes;$i++)
{
shuffle($arr);
foreach($keywordArr AS $v) isset($hash[$v]);
}
$resultArr['hash'] = gettimeofday();
hukeok 2010-06-29
  • 打赏
  • 举报
回复
学习了
amani11 2010-06-29
  • 打赏
  • 举报
回复
因为key必须唯一,就使得array_flip会丢失重复的元素【保留一个】
加载更多回复(7)

21,887

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧