PHP多维关联数组性能或类似Java代码


PHP multidimentional associative array performance or similar code in Java

我在PHP中使用下面的代码做了很多操作。问题是PHP变得越来越慢,因为我的数据越来越大。

我解决这个问题的办法是在Java中移动代码,这样它就可以提供更好的性能,因为它是编译语言,我也可以多线程或使用异步函数来做多个这样的操作,使它更快。

我想知道的是如何在PHP中加速这种操作,或者我应该使用什么其他数据结构来提高这段代码的性能。如果不是PHP,我怎么能在Java中做到这一点呢?
        foreach ( $dataArr as $direct ) {
            //total dfpimpr for the date-li combi
            if ( isset( $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']]['COUNTER_TOTALIMPR'] ) ) {
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']]['COUNTER_TOTALIMPR'] += $direct[0]['DFPIMPR'];
            }else {
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']]['COUNTER_TOTALIMPR'] = $direct[0]['DFPIMPR'];
            }
            $dfpAdUnit = $direct['AD1']['DFPAD1'].'/'.$direct['AD2']['DFPAD2'];
            // can go on the first level of the array as not dependent on AD1/AD2-COUNTRY
            if ( isset( self::$orderLineitemSetting[$direct['DOX']['ORDID']][$direct['DLI']['LIID']]['setting']['is_direct'] ) ) {
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['ISDIRECT'] = self::$orderLineitemSetting[$direct['DOX']['ORDID']][$direct['DLI']['LIID']]['setting']['is_direct'];
            }else {
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['ISDIRECT'] = 1;
            }
            if ( isset( self::$orderLineitemSetting[$direct['DOX']['ORDID']][$direct['DLI']['LIID']]['setting']['is_ron'] ) ) {
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['ISRON'] = self::$orderLineitemSetting[$direct['DOX']['ORDID']][$direct['DLI']['LIID']]['setting']['is_ron'];
            }else {
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['ISRON'] = 0;
            }
            $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['DATE'] = $direct['DS']['DATE'];
            $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['ISADEX'] = 0;
            $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['ISMM'] = 0;
            $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['ADVERTISER'] = $direct['DA']['ADVERTISER'];
            $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['ORDID'] = $direct['DOX']['ORDID'];
            $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['ORDNAME'] = $direct['DOX']['ORDNAME'];
            $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['LINAME'] = $direct['DLI']['LINAME'];
            $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['LIID'] = $direct['DLI']['LIID'];
            $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['LISIZE'] = $direct['DSZ']['LISIZE'];
            $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['SITEID'] = $direct['PUBSITE']['SITEID'];
            $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['COUNTRYID'] = $direct['DC']['COUNTRYID'];
            $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['COUNTRY'] = $direct['DC']['COUNTRY'];
            $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['DFPADUNIT'] = $dfpAdUnit;

            //if it is passback (ISDIRECT=2) make its revenue && impr = 0
            //and add its impr to a new pbImpr column
            if ( isset( self::$orderLineitemSetting[$direct['DOX']['ORDID']][$direct['DLI']['LIID']]['setting']['is_direct'] )
                && self::$orderLineitemSetting[$direct['DOX']['ORDID']][$direct['DLI']['LIID']]['setting']['is_direct'] == 2 ) {
                //passback imprs
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['PBIMPR'] = $direct[0]['DFPIMPR'];
                //make dfpimpr for passback all 0
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['DFPIMPR'] = $direct[0]['DFPIMPR'];
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['DFPCLCKS'] = $direct[0]['DFPCLCKS'];
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['DFPREV'] = 0;
                //make tpimpr for passback all 0
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['TPIMPR'] = 0;
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['TPCLCKS'] = 0;
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['TPREV'] = 0;
            }else {
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['DFPIMPR'] = $direct[0]['DFPIMPR'];
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['DFPCLCKS'] = $direct[0]['DFPCLCKS'];
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['DFPREV'] = $direct[0]['DFPREV'];
                //include direct data into 3rd party
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['TPIMPR'] = $direct[0]['DFPIMPR'];
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['TPCLCKS'] = $direct[0]['DFPCLCKS'];
                $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['TPREV'] = $direct[0]['DFPREV'];
            }
            //include direct data into 3rd party
            $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['TP'] = '';
            $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']]['TPTAGID'] = 0;
        }
  1. 遵循DRY原则。这样就可以减少代码的长度和复杂性,而且——在这种情况下最重要的是——您将摆脱几十个多维数组解引用。最后的代码也更容易维护:

    foreach ($dataArr as $direct) {
        // create a few references to reduce "ugly" code
        $counter      = &$arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']]['COUNTER_TOTALIMPR'];
        $directStatus = &self::$orderLineitemSetting[$direct['DOX']['ORDID']][$direct['DLI']['LIID']]['setting']['is_direct'];
        $ronStatus    = &self::$orderLineitemSetting[$direct['DOX']['ORDID']][$direct['DLI']['LIID']]['setting']['is_ron'];
        $dfpAdUnit = $direct['AD1']['DFPAD1'].'/'.$direct['AD2']['DFPAD2'];
        if (!isset($counter)) {
            $counter = 0;
        }
        $counter += $direct[0]['DFPIMPR'];
        $e = array(
            'DATE'       => $direct['DS']['DATE'],
            'ISADEX'     => 0,
            'ISMM'       => 0,
            'ADVERTISER' => $direct['DA']['ADVERTISER'],
            'ORDID'      => $direct['DOX']['ORDID'],
            'ORDNAME'    => $direct['DOX']['ORDNAME'],
            'LINAME'     => $direct['DLI']['LINAME'],
            'LIID'       => $direct['DLI']['LIID'],
            'LISIZE'     => $direct['DSZ']['LISIZE'],
            'SITEID'     => $direct['PUBSITE']['SITEID'],
            'COUNTRYID'  => $direct['DC']['COUNTRYID'],
            'COUNTRY'    => $direct['DC']['COUNTRY'],
            'DFPADUNIT'  => $dfpAdUnit,
            'TP'         => '',
            'TPTAGID'    => 0
        );
        $e['ISDIRECT'] = !isset($directStatus) ? 1 : $directStatus;
        $e['ISRON']    = !isset($ronStatus) ? 0 : $ronStatus;
        if (isset($directStatus) && $directStatus === 2) { // Hint: don't use magic numbers (2),
                                                           // create some constant with appropriate name
            $e += array(
                'PBIMPR'   => $direct[0]['DFPIMPR'],
                'DFPIMPR'  => $direct[0]['DFPIMPR'],
                'DFPCLCKS' => $direct[0]['DFPCLCKS'],
                'DFPREV'   => 0,
                'TPIMPR'   => 0,
                'TPCLCKS'  => 0,
                'TPREV'    => 0
            );
        } else {
            $e += array(
                'DFPIMPR'  => $direct[0]['DFPIMPR'],
                'DFPCLCKS' => $direct[0]['DFPCLCKS'],
                'DFPREV'   => $direct[0]['DFPREV'],
                'TPIMPR'   => $direct[0]['DFPIMPR'],
                'TPCLCKS'  => $direct[0]['DFPCLCKS'],
                'TPREV'    => $direct[0]['DFPREV']
            );
        }
        $arrayToBeFilled[$direct['DS']['DATE']][$direct['DLI']['LIID']][$dfpAdUnit][$direct['DC']['COUNTRYID']] = $e;
    }
    
  2. 优化PHP本身。使用OP代码加速器,如APC(用于PHP <@Alasdair

  3. 建议使用JIT编译器(HHVM)。