【问题标题】:Return a value or modify reference?返回值或修改引用?
【发布时间】:2011-04-08 08:46:23
【问题描述】:

我以前都见过,据我所知,这非常主观,但如果可以选择,你会怎么做?为什么?如果数据很大,其中一个是否会对速度/内存有任何好处?

function processData(&$data_to_process) { // Pass by reference.
    // do something to the data
}

// ... somewhere else

$this->processData($some_data);

function processData($data_to_process) { // Pass by value.
    // do something to the data
    return $data_to_process;
}

// ... somewhere else

$some_data = $this->processData($some_data);

【问题讨论】:

    标签: php performance pass-by-reference pass-by-value choice


    【解决方案1】:

    在大多数情况下,返回调用者已经拥有的引用是多余的,这就是您的第二个示例中发生的情况。我能想到的唯一有用的地方是链接方法调用。

    一般来说,当函数将改变参数状态时使用引用参数,并使用返回值向调用者引入新的东西。

    【讨论】:

    • 在 PHP 中,第二个不是按引用传递,而是按值传递,因此修改它不会编辑数据。我知道这并非适用于所有语言(例如 Java),所以我猜这个问题不一定适用于所有语言。
    【解决方案2】:

    PHP 在写入时复制,所以如果函数中的数据没有改变,使用引用只会让事情运行得更慢。

    在您的情况下,您正在更改数据,因此会发生副本。使用以下内容进行测试:

    <?php
    
    define('N', 100000);
    $data = range(1, N);
    srand(1);
    
    function ref(&$data)
    {
            $data[rand(1, N)] = 1;
    }
    
    function ret($data)
    {
            $data[rand(1, N)] = 1;
            return $data;
    }
    
    echo memory_get_usage()."\n";
    echo memory_get_peak_usage()."\n";
    
    ref($data);
    // $data = ret($data);
    
    echo memory_get_usage()."\n";
    echo memory_get_peak_usage()."\n";
    
    ?>
    

    使用ref() 运行一次,使用ret() 运行一次。我的结果:

    ref()

    • 8043280(之前/现在)
    • 8044188(前/高峰)
    • 8043300(之后/当前)
    • 8044216(后/峰)

    ret()

    • 8043352(之前/现在)
    • 8044260(前/高峰)
    • 8043328(后/当前)
    • 12968632(后/峰)

    因此,如您所见,PHP 在修改函数中的数据并返回时使用了更多内存。所以最佳情况是通过引用传递。

    但是,如果通过引用传递的发生并不明显,那么它可能会很危险。通常,您可以通过将数据封装在修改自己数据的类中来完全避免这个问题。

    请注意,如果您使用对象,PHP5 总是通过引用传递它们。

    【讨论】:

    • 好吧,很酷。感谢您回答问题的两个部分。
    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 2012-07-07
    • 1970-01-01
    • 2011-11-23
    • 2014-08-24
    • 2016-08-03
    • 1970-01-01
    相关资源
    最近更新 更多