2012-06-17 64 views
28

Có bất kỳ vấn đề nào liên quan đến hiệu quả, khi sử dụng cuộc gọi hàm trong vòng lặp foreach. Ví dụ:Sử dụng cuộc gọi chức năng trong vòng lặp foreach

foreach ($this->getValues() as $value) { 
    //Do something with $value 
} 

so

$values = $this->getValues(); 
foreach ($values as $value) { 
    //Do something with $value 
} 

Về cơ bản, là php đủ thông minh để gọi $ this-> getValues ​​() một lần duy nhất trong ví dụ đầu tiên, hoặc dùng nó gọi nó là trên mỗi lần lặp. Nếu nó gọi nó trên mỗi lần lặp, sau đó như thế nào theo dõi trong đó yếu tố hiện tại,

+0

* mọi thứ * bạn làm bên trong vòng lặp sẽ giảm hiệu quả. – goat

+0

Vâng, nhược điểm duy nhất với phương pháp thứ hai là bạn yêu cầu một biến phụ (chiếm bộ nhớ). Vì vậy, tôi sẽ đi với cách tiếp cận đầu tiên. –

+1

trụ, "biến phụ" không thực sự ở đó. PHP sử dụng copy-on-write có nghĩa là '$ values' và foreach loop sẽ tham chiếu cùng một tập dữ liệu. Điều duy nhất cần xem xét là khi biến có thể được thu thập rác, mà là trước đó trong ví dụ đầu tiên (ở cuối vòng lặp) hơn trong lần thứ hai (ở cuối hàm/tệp hoặc khi 'unset()' là gọi là). –

Trả lời

32

Cả hai đều là về cơ bản giống nhau:

foreach ($this->getValues() as $value) { 
// 
} 

$values = $this->getValues(); 
foreach ($values as $value) { 
    // 
} 

$this->getValues() sẽ chỉ chạy một lần, vì nó không phải là bên trong bản thân vòng lặp. Nếu bạn cần sử dụng lại giá trị trả về của getValues, hãy tiếp tục và gán nó vào một biến để bạn không phải gọi lại hàm đó. Nếu không, bạn không thực sự cần một biến.

+0

Vì vậy, categorically, $ this-> getValues ​​() được gọi một lần, và chỉ một lần? –

+7

Đó là chính xác, nhưng tôi không chắc chắn những gì bạn có nghĩa là "categorically". Tại sao bạn không thử nghiệm nó? Có getValues' đăng nhập một tin nhắn hoặc đầu ra một cái gì đó trực tiếp với echo trước khi trở về mảng để bạn có thể xem bao nhiêu lần nó được gọi. –

15

Có thể có sự khác biệt, nhưng nó sẽ không đáng kể đối với 99,9% trường hợp trong thế giới thực. Trong cả hai trường hợp, PHP sẽ chỉ gọi hàm/phương thức của bạn một lần. Điều gì xảy ra trong nội bộ khi bạn sử dụng foreach là PHP đánh giá iteratee (phần trước as) một lần, lưu trữ kết quả và sau đó lặp lại nó, đưa phần tử hiện tại vào biến cục bộ sau as. Nếu bạn viết iteratee vào một biến cục bộ, bạn thực tế chỉ cần nhân đôi nỗ lực của PHP, vì vậy cách tiếp cận đầu tiên có thể mang thêm chi phí, nhưng nó sẽ không đủ để lo lắng. Tôi muốn tối ưu hóa cho khả năng đọc thay vào đó: nếu cuộc gọi hàm ngắn và tự mô tả, hãy nội tuyến nó; nếu nó phức tạp hoặc ít người biết đến, hãy lưu trữ nó trong biến mô tả để thay thế.

Lưu ý rằng tình huống khác với các vòng lặp forwhile điển hình, đây có thể là nơi bạn có khái niệm này. Ví dụ: trong mã sau:

for ($number = 0; $number < $this->getNumberOfItems(); ++$number) { 
    // do stuff... 
} 

... phương thức getNumberOfItems() được gọi trên mọi lần lặp lại. Trong tình huống này, nó có ý nghĩa để tính toán trước nó và lưu trữ nó trong một biến cục bộ.

+0

Khi bạn nói * để cách tiếp cận đầu tiên có thể mang thêm chi phí * Tôi nghĩ bạn có nghĩa là * cách tiếp cận thứ hai * – whoan

Các vấn đề liên quan