0

好的。所以我一直在努力弄清楚为什么我的脚本需要永远运行。我已经确定了一个潜在的原因,并想找出一种更有效的方法来执行以下功能:

function getwrs($obj, $recs) {
    foreach ($obj as $key => $val) {
        for ($i=0; $i<count($recs); $i++) {
            $wr = array();
            if ($recs[$i][0] === $key) {
                $wr = $recs[$i];
                break;
            }
        }
        if (count($wr) > 0) {
            for ($i=0; $i<count($val); $i++) {
                if ($val[$i]["time"] < $wr[1] && abs($wr[1] - $val[$i]["time"]) < 30) {
                    $uwrs[] = array($val[$i], $wr);
                }
            }
        }
    }
    return $uwrs;
}

我这样调用这个函数:

$wrs = getwrs($top15["pro"], $recs);

其中$top15["pro"]是具有以下结构的多维数组:

[MAP1NAME] => Array
(
    [0] => Array
    (
        [authid] => XXXX
        [name] => XXXX
        [time] => XXXX
        [date] => XXXX
        ...
    )
)
[MAP2NAME] => Array
(
    [0] => Array
    (
        [authid] => XXXX
        [name] => XXXX
        [time] => XXXX
        [date] => XXXX
        ...
    )
    [1] => Array
    (
        [authid] => XXXX
        [name] => XXXX
        [time] => XXXX
        [date] => XXXX
        ...
    )
    ...
)

并且包含超过 1500 个条目,$recs 是一个包含可比较值和大约 3000 个条目的数组,结构如下:

[0] => Array
    (
        [0] => MAP1NAME
        [1] => TIMEVAL
        [2] => USERNAME1
        [3] => COUNTRY
    )
    ...

此函数的目的是通过比较我数据库中每张地图的$top15时间值 ( ) 与官方世界记录数组 ( $recs) 中的时间值来查找非官方世界纪录。

现在我从我的数据库中获取每个地图名称,并从官方世界记录数组中找到相同的字符串,然后$wr如果有官方记录,则将地图的官方世界记录值存储在一个变量中。接下来,我遍历数据库中的已完成时间数组,以查找哪些时间(如果有)小于官方记录时间。每次这是真的,我将与我的数据库时间和官方记录时间(用户、时间等)有关的信息都推送到一个新数组中。对我数据库中的每个键(地图名称)重复此操作。最后,该函数返回我的非官方世界记录数组 ( $uwrs)。

问题很简单:由于某种原因,这需要太长时间。我最初用 JavaScript 编写了我的脚本,它的响应速度非常快,所以我可能认为我在这里做错了什么。有什么帮助吗?

编辑:我使用 xdebug 来查明问题,当我添加对该函数的调用时,我的输出文件从 3MB 变为超过 30MB,脚本运行时间从大约 1 秒变为 15-20 秒。我对这个工具比较陌生,所以我不知道这个信息是否重要。

编辑2:根据要求,我的数据库结构如下:

map | authid | name | time | date | weapon

前任:

kzbr_brickngrasshop | STEAM_0:1:XXXXXXX | John Travolta kz-endo | 23.582824 | 2013-08-25 | 03:40:17 | knife
4

2 回答 2

1

多次阅读您的问题后,我假设您需要一种方法来比较来自两个不同表的数据。

出于演示目的和简单性,假设您有两个表officialunofficial.

officialunofficial表共享相同的结构,即-

------------+-------------+----------+----------+-----------
    mapid   |    authid   |   name   |   time   |   date
------------+-------------+----------+----------+-----------
  map1name  |    1        |   bob    | 03:40:17 | 2013-08-25
------------+-------------+----------+----------+-----------
  map2name  |    2        |   hop    | 01:10:56 | 2012-04-12
------------+-------------+----------+----------+-----------
  map3name  |    3        | cherry   | 11:08:14 | 2013-05-14
------------+-------------+----------+----------+-----------
  map4name  |    4        |   adam   | 09:16:43 | 2013-07-10
------------+-------------+----------+----------+-----------
  map5name  |    5        |   zyl    | 06:01:53 | 2012-09-30
------------+-------------+----------+----------+-----------

现在你可以做的是执行一些高级 mysqlqueries 从两个表中查找数据。

SELECT * FROM `unofficial` JOIN `official` WHERE `official.mapid` = `unofficial.mapid` AND TIME_TO_SEC(`official.time`) > TIME_TO_SEC(`unofficial.time`) AND  ABS( TIME_TO_SEC(`official.time`) - TIME_TO_SEC(`unofficial.time`) ) < 1800

这里做了什么:

在这里,我们执行了一个 mysql 查询,在执行三个条件后连接了表并获取结果 -

(i) 他们的地图 ID 必须相同。从您上面的代码中,我认为您想匹配两个表中的地图 ID,以便找到非官方的世界记录。

(ii)unofficial上桌时间必须少于official上桌时间。我再次从您上面的代码中假设它。TIME_TO_SECmysql将时间转换为秒的函数。像 TIME_TO_SEC('01:01:06') 返回 3666。

(iii) 与第三种是时间差低于 30 秒。再次在您的代码中。

我的查询可能有一些错误,例如拼写错误或选择错误的列等,因为我没有针对真实数据库对其进行测试。但这个想法几乎是一样的。您可以搜索相应的查询或阅读文档。

我希望这会对你有所帮助。

于 2013-09-13T17:51:50.203 回答
0

通过创建 13,000,000 个不同的变量并在执行循环之前将它们设置为每个数组的长度来解决该问题。阅读显示我数到 1500/3000/等。每次我使用 for 循环。猜猜它会影响PHP的性能..

于 2013-09-13T17:49:31.743 回答