2012-04-13 30 views
8

Các yêu cầu đối với đơn đăng ký của tôi như sau. Tôi cần phải lưu trữ đơn hàng giống như thế này:Cấu trúc dữ liệu C# tốt nhất cho các tình huống sau đây

  • Mỗi trật tự gắn liền với một stockcode cụ thể (string) và có một mức giá, khối lượng và có hay không nó đang được mua hoặc bán (boolean) liên kết với nó.

  • Tôi cần thực hiện một số thao tác trên tất cả các đơn đặt hàng liên quan đến một cổ phiếu cụ thể, ví dụ lấy tổng khối lượng đơn đặt hàng cho mã "abc".

  • tôi cần để có thể thêm lệnh cấu trúc dữ liệu

  • tôi cần để có thể loại bỏ một đơn đặt hàng từ các cấu trúc dữ liệu

  • tôi cần để có thể tìm ra đơn đặt hàng đang cung cấp mức giá tốt nhất sau khi đơn đặt hàng được thêm hoặc xóa.

Dưới đây là những gì tôi đang suy nghĩ cho đến nay:

public class Order : IComparable 
{ 

    private string _StockCode; 
    private bool _BidSide; 
    private int _Volume; 
    private decimal _Price; 
    private int _ExchangeOrderId; 

    public int CompareTo(Order other) 
    { 
     if (_BidSide != other.BidSide) 
     { 
      return _BidSide ? 1 : -1; 
     } 
     return decimal.Compare(_Price, other.Price); 
    } 
} 

Và sau đó tôi sẽ lưu trữ các đơn đặt hàng trong một từ điển < chuỗi, Danh sách < tự > >. Trường hợp mỗi mã cổ phiếu sẽ là một chìa khóa trong từ điển trỏ đến một danh sách các đơn đặt hàng cho cổ phiếu đó. Tôi cũng sẽ duy trì từ điển khớp với id đơn đặt hàng với mã chứng khoán.

  • Để thêm đơn đặt hàng mới, tôi chỉ cần tìm danh sách đơn đặt hàng thích hợp trong từ điển dựa trên mã chứng khoán hiện tại và chèn thứ tự. Tôi cũng sẽ thêm một mục trong từ điển orderstock khớp với thứ tự hiện tại với danh sách approrpriate.

  • Để tìm giá tốt nhất, tôi tra cứu danh sách đơn hàng trong từ điển cho mã chứng khoán hiện tại, sắp xếp danh sách và in ra thứ tự cao nhất.

  • Xóa là khó khăn. Trước tiên, tôi cần tìm kiếm danh sách thích hợp bằng mã chứng khoán. Sau đó, tôi sẽ cần phải lặp qua tất cả các đơn đặt hàng cho mã chứng khoán đó và tìm mã khớp với id đơn đặt hàng hiện tại và xóa nó. Điều này rõ ràng là không hiệu quả nếu có rất nhiều đơn đặt hàng cho mã cổ phiếu hiện tại. Đây có phải là cách tốt nhất để lưu trữ thông tin này không?

+0

Điều gì đó ngu ngốc, nhưng các tiêu chuẩn cho biết sau khi _ đi chữ thường. –

+0

"Điều này rõ ràng là không hiệu quả nếu có rất nhiều đơn đặt hàng cho mã cổ phiếu hiện tại." Có và không. Nó phụ thuộc vào "rất nhiều" và tần suất bạn mong muốn xóa một đơn đặt hàng. Nếu bạn đang xóa hàng trăm đơn đặt hàng một giây và bạn có thể có 1.000 đơn đặt hàng trên mỗi cổ phiếu, thì nó sẽ chậm. Nhưng nếu bạn đang nói hàng chục đơn đặt hàng cho một cổ phiếu và xóa một đơn đặt hàng là không thường xuyên, sau đó "không hiệu quả" không phải là một vấn đề. –

+3

Bất kỳ lý do nào không có trong cơ sở dữ liệu? Chúng được thiết kế riêng cho loại hành vi này ... – Telastyn

Trả lời

1

Nếu bạn định làm điều này với nhiều dữ liệu, hãy đặt nó vào cơ sở dữ liệu. Đây không phải là điều bạn muốn làm trong lớp học.

Tuy nhiên, nếu bạn đang sử dụng một tập dữ liệu nhỏ, bạn có thể thực hiện việc này bằng mã bằng LINQ.

Tôi nghĩ bạn nên đặt Đơn hàng thực hiện IEnumerable và sau đó sử dụng List<Order> để lưu trữ đơn đặt hàng của bạn.Hãy StockCode một tài sản công cộng trên Order và sau đó bạn có thể lấy đơn đặt hàng bằng cách sử dụng LINQ:

List<Order> orders = GetOrderList(); 

var ibmOrders = from o in orders 
    where o.StockCode == "IBM" 
    select o; 

mục Loại bỏ khỏi danh sách là khá đơn giản:

List<Order> orders = GetOrderList(); 

var orderToRemove = (from o in orders 
    where o.ExchangeId == 1315 
    select o).FirstOrDefault(); 

if (orderToRemove != null) { 
    orders.Remove(orderToRemove); 
} 

Finding bởi mức giá tốt nhất sử dụng LINQ là khá đẹp :

Order bestPricedOrder = (from o in orders 
     orderby Price 
     select o).FirstOrDefault(); 

Để biết các thủ thuật LINQ tuyệt vời hơn, hãy xem 101 LINQ Samples.

+0

Min/max trong LINq là tất cả O (n). Nếu có một số lượng công bằng của các đối tượng, truy cập thường xuyên vv nó không phải là một lựa chọn hiệu quả. Nó cũng không thực sự tốt hơn đề nghị OP. Ngoài ra, 'Order' là số ít từ việc tôi đọc OP. Bạn cần phải tạo một lớp mới cho việc thu thập các đơn đặt hàng. Danh sách OP được sử dụng. Thêm/loại bỏ vào danh sách các đơn đặt hàng cũng sẽ tồi tệ hơn nhiều so với 'Dictionary' thêm/xóa. – Servy

+0

Ý kiến ​​tốt Servy. Tôi không thấy có bao nhiêu đối tượng mà OP đang có kế hoạch sử dụng nên tôi nghĩ LINQ sẽ là một gợi ý cho các tập hợp dữ liệu nhỏ. Tôi cũng nghĩ rằng LINQ sẽ dẫn đến mã dễ đọc hơn nhiều (đọc: duy trì) và do đó sẽ là một giải pháp tốt hơn so với cách tiếp cận ban đầu. –

+1

Tất cả các cấu trúc dữ liệu mà OP sử dụng thực hiện 'IEnumerable', vì vậy bạn vẫn có thể sử dụng LINQ. Mã của bạn không thêm cải thiện về vấn đề đó.Ngoài ra, nếu ai đó hỏi, "có cách nào hiệu quả hơn để thực hiện việc này không" và bạn cho rằng hiệu suất không phải là vấn đề, chỉ cần nói như vậy và để họ làm bất cứ điều gì thay vì gợi ý điều gì đó ít hiệu quả hơn. Tôi đồng ý hiệu suất có thể không phải là một vấn đề, nhưng nếu OP nói rằng tôi sẽ trả lời cho phù hợp ngay cả khi tôi đặt câu hỏi về tính hợp lệ. – Servy

0

Tôi đồng ý với nhận xét rằng cơ sở dữ liệu sẽ là lựa chọn tốt nhất; chúng được thiết kế cho loại điều này.

Nếu bạn cần giữ dữ liệu này trong bộ nhớ và thực sự có rất nhiều Đơn đặt hàng trên mỗi mã, thì tôi sẽ đi với một số Dictionary<string, SortedSet<Order>>. SortedSet sẽ làm cho việc tìm kiếm min/max dễ dàng, cũng như chèn/xóa nhanh chóng.

+0

Cơ sở dữ liệu là cách để đi nếu bạn cần sự kiên trì, giao dịch và những thứ như thế này. Một giải pháp bộ nhớ có thể khá nhanh (rõ ràng) và lý tưởng tùy theo nhu cầu của OP (Tôi cho rằng tôi cũng sẽ đòi hỏi sự kiên trì và giao dịch;)) Có lẽ OP chỉ lên kế hoạch không bao giờ tắt máy tính hoặc có nó sụp đổ;) Bao gồm hoán đổi bộ nhớ nóng khi dữ liệu quá lớn: D – Jordan

+0

Tôi cho rằng ví dụ như một ví dụ có thể xem xét các phiên asp.net. Chúng hỗ trợ bộ nhớ trong, máy chủ trạng thái và tùy chọn cơ sở dữ liệu tùy thuộc vào nhu cầu của bạn. – Jordan

1

Tôi sẽ thêm từ điển bổ sung, bao gồm khóa = orderid, value = reference vào thứ tự trong danh sách trong từ điển ban đầu của mã cổ phiếu.

Điều này sẽ hoạt động giống như chỉ mục và cung cấp cho bạn thời gian xóa liên tục. Giả sử bạn ID đặt hàng là khác biệt, nó sẽ ánh xạ 1: 1. Chỉ cần chắc chắn rằng bạn xóa nó khỏi cả hai bộ từ điển.

Như được đề xuất trong các nhận xét, tôi khuyên bạn nên thêm từ điển của các khoản tiền được tính mà bạn cần có thể truy cập bằng mã chứng khoán. Đây là giao dịch không tiếp tục truy cập thời gian cho bộ nhớ. Trừ khi bộ nhớ là một vấn đề này sẽ có vẻ thuận lợi để tính toán nó mỗi khi bạn cần nó. Nếu bạn nhận được một đơn đặt hàng mới trong bạn chỉ có thể cập nhật số tiền, trung bình, vv Chỉ cần ghi nhớ nếu bạn đang làm công cụ song song bạn sẽ cần một số khóa để đảm bảo bạn không có vấn đề.

+0

PS to OP, Cool name Fonzie;) – Jordan

+1

Trong cùng một hương vị, tôi sẽ thêm một lớp mô tả trạng thái của giá thầu vào bộ nhớ cache trung bình, giá thầu cao nhất, v.v ... sẽ được cập nhật với mỗi lần xóa/bổ sung giá thầu và sẽ lưu trữ danh sách giá thầu hiện tại. Bằng cách này, việc cập nhật của bạn có thể nhanh hơn rất nhiều. Tất cả các đề xuất khác để đi đến một cơ sở dữ liệu thêm giá trị nhưng phức tạp, bên cạnh việc sử dụng PLINQ trên bộ nhớ trong, bạn có thể có được hiệu suất đáng kinh ngạc. – payo

+1

@payo Caching giá tốt nhất cho toàn bộ thỏa thuận sẽ không được xấu, nhưng bộ nhớ đệm giá tốt nhất cho mỗi mã sẽ tăng lên khá nhanh, và không mua gần như nhiều về lợi ích bổ sung. Tôi muốn tránh nó trừ khi có bằng chứng thuyết phục hấp dẫn nó đã giúp. – Servy

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