Tell-dont-ask princible使用更多内存,如何做出妥协?

时间:2017-08-05 13:46:44

标签: php memory tell-dont-ask

add_filter('woocommerce_available_payment_gateways', 'conditional_payment_gateways', 10, 1);
function conditional_payment_gateways( $available_gateways ) {

    foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        // Get the WC_Product object
        $product = wc_get_product($cart_item['product_id']);
        // Only for variable products
        if($product->is_type('variable')){
            // Get the Variation "min" price
            $variation_min_price = $product->get_variation_price('min');
            // If the product category match with the variation 'min" price
            if( has_term( $variation_min_price, 'product_cat', $cart_item['product_id'] ) ){
                // Cash on delivery (cod) payment gateway
                unset($available_gateways['cod']); // unset 'cod'
                break; // stop the loop
            }
        }
    }
    return $available_gateways;
}

这说明了整个BAD和GOOD的用法。

call.respondHtml(block = block) 很糟糕,因为传递一个对象对于函数来说是一个不必要的知识,但MEMORY-GOOD,因为它只传递一个引用,而不是整个数组本身

class Operation { private $op; public function __construct() { $this->op = []; for ($i = 1; $i < 1000; $i++) { $this->op[] = rand(1,9999); } } public function getOps() { return $this->op; } } class TestTellDontAsk { public function doItBAD(Operation $op) { foreach($op->getOps() as $item) { echo $item.'; '; } } public function doItGOOD(array $ops) { foreach($ops as $item) { echo $item.'; '; } } } $m = [ memory_get_peak_usage(true), memory_get_peak_usage(false), memory_get_peak_usage(true), memory_get_peak_usage(false) ]; $op = new Operation(); switch(mt_rand(0,1)) { case 0: (new TestTellDontAsk())->doItBAD($op); break; case 1: (new TestTellDontAsk())->doItGOOD($op->getOps()); break; } echo '<hr>'; echo memory_get_peak_usage(true) - $m[0].'<br>'; echo memory_get_peak_usage(false) - $m[1].'<br>'; echo memory_get_peak_usage(true) - $m[2].'<br>'; echo memory_get_peak_usage(false) - $m[3].'<br>'; 很好,因为它只传递一个数组而不是MEMORY-BAD,因为它只是传递了所有数据而不是引用。

现在如何决定使用哪一个?

1 个答案:

答案 0 :(得分:1)

这是一个比简单地“告诉不要问”更广泛的问题。这里有两个概念。将一个与另一个进行权衡是很常见的。

  • 良好的软件设计
  • 高效的软件设计

这两个概念都是主观的。什么构成良好的代码是无休止地争论。 “高效”软件具有多种不同的含义,具体取决于上下文(例如:高效的CPU,或高效的内存)。

因此,对这个问题的任何答案都是主观的,并且是开放的。有人会说这不是一个好的堆栈溢出问题。

何时为了提高效率而编写“不太好”的代码?

这是经验。

如果您没有这方面的经验,那么这里有一些想法的提示:

  • 此代码对性能有多重要?它是每天执行一次还是每天执行十亿次并且有一百万个并发线程?
  • 性能有多大?每天减少1秒CPU时间并不值得担心。它不值得担心奇数KB的RAM。但是,如果这段代码是500MB或1/2MB之间的差异,那么你可能应该仔细考虑一下。
  • 你打破了多少原则?如果一个类中的9/10函数获取该对象,并且只有一个函数可以仅使用该数组,那么您就不太可能提高代码那么多。你可能实际上打破了principle of least astonishment
  • 开发时间。让我们说你的时间是每小时100美元?在5分钟内完成不完美的答案时,是否能找到完美的答案,值2小时?有时答案就是“是的!”。通常答案是“不”。

经验法则

坏:如果你没有性能要求,那就不要担心性能问题。 我花了太多年时间修复这些人的代码。这是一种虚假的经济。

更好:如果你没有特别的理由担心性能,那就不要......但是你要去测试性能。这样,您的代码在投入生产时可能会有效。

更明确地说:以牺牲性能为代价去做好设计。只有在需要时才能提高性能。