2012-05-02 36 views
6

Giả sử nếu điều này là mã:Trong PHP, làm thế nào để chúng ta trả về một mảng lớn?

function bar() { 
    $result = array(); 
    for ($i = 0; $i < 1000; $i++) { 
     $result[] = $i * 10; 
    } 
    return $result; 
} 

$ha = bar(); 
print_r($ha); 

Há chẳng phải hiệu quả để trả lại một mảng lớn như vậy vì nó là "trở lại theo giá trị"? (nói nếu nó không phải là 1000 nhưng 1000000). Vì vậy, để cải thiện nó, chúng ta sẽ có sự thay đổi người đầu tiên:

function &bar() { 

có nghĩa là, chỉ bằng cách thêm một & ở phía trước của tên hàm - đây là một cách chính xác và ưa thích nếu một mảng lớn được trả lại?

Trả lời

7

Có rất nhiều hiểu lầm về cách PHP xử lý lưu trữ biến. Vì PHP là "copy on writing", không cần phải tạo một "reference" (thực sự là một bí danh bảng biểu tượng) trong một nỗ lực để tiết kiệm không gian hoặc thời gian. Trong thực tế, làm như vậy có thể làm tổn thương bạn. Bạn chỉ nên chỉ tạo tham chiếu bằng PHP nếu bạn muốn sử dụng nó làm bí danh cho một cái gì đó. Tôi đã chạy cả hai đoạn mã của bạn và có vẻ như thứ hai thực sự sử dụng bộ nhớ hơn (mặc dù không nhiều).

Nhân tiện, một mảng 1000 số nguyên là nhỏ.

5

Họ tiêu thụ hoàn toàn cùng một lượng bộ nhớ, vì COW

  1. http://ideone.com/bZgm7
  2. http://ideone.com/e3Jfr

PS: để có được "true" đi ngang qua tham khảo bạn cũng cần phải thêm nó trong nhiệm vụ:

$ha =& bar(); 
+0

Chỉ định nghĩa chức năng mới có thể có biển báo tham chiếu, chứ không phải hàm gọi –

+2

@Jack: vui lòng đọc tài liệu (* cẩn thận *) và undownvote me: http://nz.php.net/manual/en/language.references.return.php (đặc biệt là lưu ý đầu tiên: "Không giống như thông số đi qua, ở đây bạn phải sử dụng & ở cả hai nơi") – zerkms

+0

Lời xin lỗi của tôi, tôi đứng sửa .. khá mơ hồ thứ tôi phải nói :) –

0

Điều này thì sao?

function bar($result) { 
    $result = array(); 
    for ($i = 0; $i < 1000; $i++) { 
     $result[] = $i * 10; 
    } 
} 

bar(&$ha); 
print_r($ha); 
3

Nếu bạn ném memory_get_peak_usage() vào chức năng và bên ngoài, bạn sẽ thấy trả về mảng không làm tăng bộ nhớ.

Sao chép PHP khi viết. Trong trường hợp này, không có gì để sao chép ngay cả khi bạn viết vì biến ban đầu nằm ngoài phạm vi. Vì vậy, không, không có lý do để làm điều này. Trên thực tế, trong PHP, thường không có lý do gì để sử dụng tài liệu tham khảo trừ khi bạn cần chức năng mà chúng cung cấp: thay đổi biến ban đầu.

+0

Vì vậy, sau khi chúng tôi lấy lại mảng, nếu chúng ta thay đổi ngay một phần tử mảng hoặc thêm một phần tử cho mảng, nó được coi là "ghi", nhưng sẽ không có "copy on write"? –

+0

@Jeremy L: nếu bạn thay đổi mảng bên ngoài hàm - chỉ có một tham chiếu tồn tại, do đó sẽ không có bản sao nào được thực hiện. nó sẽ được coi là viết, nhưng không có bản sao (bởi vì chỉ có một tham chiếu tồn tại) – zerkms

+0

@Jeremy L: sẽ không có bản sao viết vì nó là tham chiếu duy nhất cho mảng đó. Nếu bạn đã trả về một biến cá thể của một đối tượng, thì sẽ có một bản sao sau khi bạn sửa đổi mảng. Tuy nhiên, trong trường hợp đó, bạn sẽ phải tự hỏi mình: tôi có thực sự muốn người gọi có thể thay đổi mảng thể hiện của đối tượng không? Vì vậy, một lần nữa, tôi sẽ lặp lại rằng như một quy tắc của ngón tay cái bạn không sử dụng tài liệu tham khảo trong PHP để đạt được hiệu suất. – Matthew

1

Trang hướng dẫn chính thức cho biết: Trả về bằng tham chiếu rất hữu ích khi bạn muốn sử dụng hàm để tìm biến nào nên tham chiếu. Không sử dụng trả lại theo tham chiếu để tăng hiệu suất. Động cơ sẽ tự động tối ưu hóa điều này một mình. Chỉ trả lại tài liệu tham khảo khi bạn có một lý do kỹ thuật hợp lệ để làm như vậy

http://it2.php.net/manual/en/language.references.return.php

Vì vậy, trong trường hợp của bạn, không sử dụng nó.

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