2012-03-16 24 views
7

Tôi tò mò về cách IEnumerable khác với IObservable dưới mui xe. Tôi hiểu các mô hình kéo và đẩy tương ứng nhưng làm thế nào C#, về bộ nhớ vv, thông báo cho thuê bao (cho IObservable) rằng nó sẽ nhận được bit tiếp theo của dữ liệu trong bộ nhớ để xử lý? Làm thế nào để các trường hợp quan sát biết nó đã có một sự thay đổi trong dữ liệu để đẩy đến các thuê bao.Làm thế nào để IEnumerable khác với IObservable dưới mui xe?

Câu hỏi của tôi xuất phát từ một bài kiểm tra tôi đang thực hiện đọc trong các dòng từ một tệp. Tập tin có tổng cộng khoảng 6Mb.

Giờ chuẩn Taken: 4.7s, dòng: 36587

Rx Time Taken: 0.68s, dòng: 36587

thế nào là Rx có thể ồ ạt cải thiện một sự lặp lại bình thường hơn so với từng dòng trong tập tin ?

private static void ReadStandardFile() 
{ 
    var timer = Stopwatch.StartNew(); 
    var linesProcessed = 0; 

    foreach (var l in ReadLines(new FileStream(_filePath, FileMode.Open))) 
    { 
     var s = l.Split(','); 
     linesProcessed++; 
    } 

    timer.Stop(); 

    _log.DebugFormat("Standard Time Taken: {0}s, lines: {1}", 
     timer.Elapsed.ToString(), linesProcessed); 
} 

private static void ReadRxFile() 
{ 
    var timer = Stopwatch.StartNew(); 
    var linesProcessed = 0; 

    var query = ReadLines(new FileStream(_filePath, FileMode.Open)).ToObservable(); 

    using (query.Subscribe((line) => 
    { 
     var s = line.Split(','); 
     linesProcessed++; 
    })); 

    timer.Stop(); 

    _log.DebugFormat("Rx Time Taken: {0}s, lines: {1}", 
     timer.Elapsed.ToString(), linesProcessed); 
} 

private static IEnumerable<string> ReadLines(Stream stream) 
{ 
    using (StreamReader reader = new StreamReader(stream)) 
    { 
     while (!reader.EndOfStream) 
      yield return reader.ReadLine(); 
    } 
} 
+0

Nếu bạn chuyển đổi thứ tự cuộc gọi của họ khi bạn đánh giá ứng dụng này, RX có còn nhanh hơn không? – user7116

+0

Thời gian bị đảo ngược! Có một số loại tối ưu hóa đang diễn ra! Trong thực tế, Rx chạy chậm hơn (khoảng 5s). – David

Trả lời

5

Linh cảm của tôi là hành vi bạn thấy đang phản ánh hệ điều hành lưu vào bộ nhớ cache tệp. Tôi sẽ tưởng tượng nếu bạn đảo ngược thứ tự của các cuộc gọi, bạn sẽ thấy một sự khác biệt tương tự về tốc độ, chỉ cần hoán đổi.

Bạn có thể cải thiện điểm chuẩn này bằng cách thực hiện một vài lần khởi động hoặc bằng cách sao chép tệp đầu vào vào tệp tạm thời bằng cách sử dụng File.Copy trước khi thử nghiệm từng tệp. Bằng cách này các tập tin sẽ không được "nóng" và bạn sẽ có được một sự so sánh công bằng.

+0

Chính xác. yeah nó có vẻ như mặc dù một số bộ nhớ đệm đang xảy ra. – David

+0

Tôi không nhận thấy sự khác biệt đáng kể về tốc độ của chúng cho một tệp có dung lượng 10MB hoặc 25Mb và sau đó tiêu chuẩn lấy bánh (tăng tốc 4x) cho tới 100MB (lớn nhất tôi đã thử) của dữ liệu được tạo ngẫu nhiên bằng dấu phẩy. Điều này bao gồm việc cho phép JIT "hâm nóng" bằng cách chạy từng phương pháp 3x trước khi đưa ra kết quả thực tế của nó. Như với bất kỳ điểm chuẩn nào, nó sẽ cụ thể cho môi trường hoạt động của bạn. – user7116

1

Tôi nghi ngờ rằng bạn đang thấy một số loại tối ưu hóa nội bộ của CLR. Nó có thể lưu trữ nội dung của tập tin trong bộ nhớ giữa hai cuộc gọi để ToObservable có thể kéo nội dung nhanh hơn nhiều ...

Edit: Oh, đồng nghiệp tốt với biệt danh điên eeh ... @sixlettervariables nhanh hơn và anh ấy có lẽ đúng: đó là hệ điều hành tối ưu hóa hơn CLR.

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