2009-08-30 32 views
5

Thực hiện chậm trễ hầu như luôn luôn là một lợi ích. Nhưng sau đó có những trường hợp khi đó là một vấn đề và bạn phải "tìm nạp" (trong Nhibernate) để háo hức tìm nạp nó.Khi nào việc đánh giá lười biếng không hữu ích?

Bạn có biết các tình huống thực tế khi đánh giá lười biếng có thể cắn bạn trở lại không…?

Trả lời

0

Tài nguyên tải lười biếng liên quan đến chuyến đi qua lại giữa người yêu cầu và nguồn cho mỗi lần tải. Trong trường hợp NHibernate, điều này có nghĩa là từ ứng dụng đến cơ sở dữ liệu (thường là trên một máy chủ khác).

Thường có chi phí liên quan đến mỗi chuyến đi (chắc chắn là dành cho NHibernate hoặc bất kỳ truy vấn DB nào khác).

Nếu bạn biết rằng bạn sẽ cần tất cả hoặc một phần đáng kể của dữ liệu, bạn nên tắt nó đi một lần và chỉ phát sinh chi phí một lần.

Ví dụ điển hình là khi bạn cần kéo lại danh sách đối tượng để điền vào hộp tổ hợp (thường thì đây sẽ là đối tượng cấu hình). Tải chậm sẽ quay trở lại cơ sở dữ liệu mỗi lần bạn thêm một thành viên danh sách vào hộp tổ hợp. Vì bạn đang đặt toàn bộ danh sách vào hộp kết hợp, bạn sẽ phải chịu rất nhiều chi phí phụ để lười tìm nạp từng đối tượng.

0

Nó cũng có thể là một vấn đề với trải nghiệm người dùng của chương trình của bạn. Mọi người sẽ vui vẻ chờ 5 giây khi một biểu ngữ được hiển thị trên màn hình trong khi tải ứng dụng, nhưng họ khinh thường phải đợi 0,25 giây khi họ đang nhập nội dung nào đó vào hộp văn bản. Nếu lượng thời gian cần để tải tất cả dữ liệu của bạn một cách háo hức không dài, bạn có thể xem xét thực hiện tại một số điểm trong luồng công việc mà mọi người chấp nhận chậm trễ (chẳng hạn như tải ứng dụng, cửa sổ bật lên, nhấn nút).

3

Đánh giá lười biếng không hữu ích trong các trường hợp hiệu suất là rất quan trọng và giá trị phải luôn đánh giá. Trong những trường hợp này, bạn tốt hơn là chỉ cần đánh giá giá trị và được thực hiện với nó, bởi vì chi phí đánh giá lười biếng sẽ bị lãng phí.

+0

Đánh giá lười biếng là cách để đạt được hiệu suất. – Zorf

+5

Không đúng. Nếu bạn phải đánh giá câu trả lời, thì chi phí phụ trội để đánh giá lười biếng tạo ra một chi phí không có lợi ích. – vy32

+0

vy32 là chính xác. Ví dụ: nếu bạn có danh sách các đối tượng được hiển thị trong danh sách trên thiết bị di động thì chế độ xem sẽ được tạo tại thời điểm các mục danh sách xuất hiện trên màn hình. Nếu một số giá trị được hiển thị trong danh sách phải được tải chậm danh sách sẽ nói lắp và tụt hậu vì danh sách mới không thể được điền đủ nhanh. – Janusz

0

Đánh giá lười biếng không hữu ích khi bạn không muốn lưu trữ giá trị, chỉ cần sử dụng nó. Nhưng điều này phụ thuộc vào việc thực hiện các đánh giá lười biếng. Một số hệ thống (như Haskell) có thể cho biết liệu một giá trị có được sử dụng lại hay không. Một số khác không thể và có thể gây rò rỉ.

2

Đánh giá lười biếng không hữu ích khi đánh giá có thể có tác dụng phụ. Đó là lý do duy nhất và đó là lý do tại sao chỉ có ngôn ngữ thuần túy chức năng mới có nó. Nếu các biểu thức có thể có các tác dụng phụ phải xảy ra theo một thứ tự nhất định thì bạn không thể có được nó.

Ngoài ra, đánh giá lười biếng chỉ đạt được hiệu suất, đó là mục tiêu chính. Và đó là lý do tại sao một số ngôn ngữ cấm tác dụng phụ, để đạt được đánh giá lười biếng cho sự thỏa hiệp đó, một hiệu ứng tốt đẹp khác của nó là cấu trúc điều khiển có thể là các chức năng thông thường.

2

Một ví dụ cho lazyness gây ra vấn đề lạ (xảy ra với tôi ngày hôm nay, trong Haskell):

import System.IO 

main = do 
    content <- readFile "foo.txt" 
    writeFile "foo.txt" content 

này ném các lỗi sau khi biên soạn & thực hiện:

foo.txt: openFile: resource busy (file is locked) 

Những gì tôi nghĩ rằng nó sẽ làm: Mở tệp foo.txt, đọc nội dung, đóng lại. Sau đó mở nó để viết, viết nội dung và đóng lại.

Điều gì thực sự đã làm: "Ah, một số nội dung. Tôi có lẽ sẽ đọc sau khi chúng tôi thực sự cần nó." Sau đó mở "foo.txt" để viết. Bắt đầu viết nội dung ... ok, bây giờ chúng ta cần nội dung. Mở foo.txt để đọc - bam!

Tôi biết nó không đáng kể để khắc phục, nhưng thật khó để tìm ra nếu bạn không biết phải tìm đâu.

+1

Đây là một vấn đề gây ra bởi I/O lười biếng, thay vì đánh giá lười biếng nói chung. Lazy I/O thực sự khá nguy hiểm và chống lại tinh thần lập trình hàm, vì nó tạo ra các hiệu ứng phụ cho các hàm cần thuần khiết (cụ thể là, đánh giá một chuỗi làm cho dữ liệu được đọc từ đĩa - một tác dụng phụ!), Dẫn đến các vấn đề chỉ như thế này, và điều này quá: http://stackoverflow.com/questions/2981582/haskell-lazy-io-and-closing-files Nhưng bạn chắc chắn có thể đánh giá lười biếng mà không có I/O lười biếng, trên thực tế, như vậy dường như là hướng hiện tại của Haskell. – Jesse

+0

Đây là một ví dụ gọn gàng! – vy32

4

Bạn không thể thực hiện giảm (ví dụ: gấp) trên dữ liệu đầu vào trong không gian cố định với đánh giá lười, vì đánh giá trễ của từng bước giảm dẫn đến độ phức tạp của không gian tuyến tính. Thay vào đó, bạn buộc phải đánh giá kết quả của mỗi bước giảm để giữ cho không gian sử dụng không đổi. Ví dụ: băm nhỏ một tệp trong Haskell. Bạn có thể có ý nghĩa tốt và đọc các tập tin đầu vào lazily chunk-by-chunk, thêm từng đoạn để tiêu hóa, nhưng đằng sau Haskell của bạn là thực sự làm cho một đoạn cho mỗi đoạn bạn thêm vào tiêu hóa, để lại toàn bộ tập tin trong bộ nhớ trong những khối này cho đến khi tiêu hóa kết quả thực sự được đánh giá. Ouch!

Xem nhận xét cuối cùng tại đây: Haskell lazy I/O and closing files

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