-1

我正在尝试编写一个处理大量数据的实用程序,内存是一个因素。不幸的是,每次我运行这组循环时,它都会吃掉 apx。14MB 的内存,因为它被执行了数千次,即使使用了 unset() 调用(是的,我知道它们并没有完全清理内存,这就是我问这个问题的原因)。我想知道是否有更简单的方法可以做到这一点。当前工作代码:

        $qr = array();
        foreach($XML->row as $row)
        {
         $ra = array();
         foreach($row as $key => $value)
         {
         $ra[$key] = $value[0];
         unset($key,$value);
         }
        $qr[] = $ra;
        unset($row,$ra);
        }
        unset($XML);
        return $qr;

另一种尝试是这样做,但它落后了。有人知道我在做什么错吗?

        $qr = array();
        while(list(,$row) = each($XML->row))
        {
         $ra = array();
         while(list($key,$value) = each($row))
         {
         $ra[$key] = $value[0];
         unset($key,$value);
         }
        $qr[] = $ra;
        unset($row,$ra);
        }
        unset($XML);
        return $qr;

基本上在第一个循环中,我只是尝试进行基本的数组/对象迭代。在第二个循环中,我试图遍历每个数组值并获取第一个元素,同时保持对象/数组索引关联。看来我最初是这样写的,因为它是唯一有效的东西(因为它循环通过一个 SimpleXML 对象)。任何关于加速这件事或弄清楚如何让它不吃内存的提示将不胜感激。

我正在寻找垃圾收集或更高效的代码的解决方案。我不打算替换 SimpleXML,因为不需要它。 更清楚的是,我正在寻找:

  • 一种无需调用内部循环即可迭代 SimpleXML 对象的方法(这只是因为我在执行 $value[0]。为什么有必要这样做?
  • 一种更有效(速度或内存方面)迭代数据的方法
4

3 回答 3

1

如果您想使用更少的内存,我建议您开始查看SAX 解析器。这是示例。用 SAX 开发解析器比较困难,但它比 SimpleXML 更有效,你可以用它来解析大的 xml 文件。

于 2012-07-23T19:26:33.017 回答
1

您的内存负载很高,因为 SimpleXML 在解析时会将整个文档加载到内存中。因此,您的unset()调用只是减少了引用计数,并且由于数据仍保留在内存中,因此不会被释放。这是使用 SimpleXML 的结果:这样做的好处是文档在内存中并表示为 PHP 对象。

如果您想减少内存使用量,则需要使用XMLReaderXML Parser之类的其他东西。这些是基于 SAX 或基于事件的,它们不会将 XML 文件加载到内存中,而是一次遍历树一个元素。由于您似乎没有使用 XPath 之类的东西,因此这是您更好的选择。

于 2012-07-23T19:27:30.310 回答
1

这不是您从 SimpleXML 对象访问数据的方式。我看到您正在使用 index [0] 来获取对象每个部分的字符串内容并将其视为数组。 它不是一个数组,它是一个对象。 这就是您应该如何访问字符串数据...示例: http: //php.net/manual/en/simplexml.examples-basic.php#example-5095

像这样的东西可以解决问题:

    $qr = array();
    foreach($XML->row as $row)
    {
     $ra = array();
     $ra['name'] = $value->name;
     $ra['name2'] = $value->name2;
     //Add a line for each element name, etc...

    $qr[] = $ra;
    unset($row,$ra);
    }
    unset($XML);
    return $qr;

它还将摆脱您的内部循环并节省您的记忆。

于 2012-07-25T13:05:29.610 回答