2009-08-17 30 views
9

Để tiết kiệm không gian và sự phức tạp của việc duy trì tính nhất quán của dữ liệu giữa các nguồn khác nhau, tôi đang xem xét lưu trữ chỉ mục bắt đầu/kết thúc cho một số chất nền thay vì lưu trữ bản thân. Bí quyết là nếu tôi làm như vậy, có thể tôi sẽ tạo ra các lát TẤT CẢ thời gian. Đây có phải là điều cần tránh không? Là nhà điều hành slice đủ nhanh tôi không cần phải lo lắng? Làm thế nào về các đối tượng mới tạo ra/phá hủy trên không?Làm thế nào nhanh là slice python


OK, tôi đã học bài học của mình. Không tối ưu hóa trừ khi có một vấn đề thực sự mà bạn đang cố khắc phục. (Tất nhiên điều này không có nghĩa là phải mã không cần thiết xấu, nhưng đó là bên cạnh điểm ...) Ngoài ra, kiểm tra và hồ sơ trước khi đến tràn ngăn xếp. = D Cảm ơn tất cả mọi người!

+8

Tại sao bạn không dùng thử? Viết một bài kiểm tra đơn giản. –

+0

Tôi đồng ý và lên tiếng bình chọn balpha nhưng tôi luôn tự hỏi làm thế nào nhanh chóng là các lát Python. Tôi sử dụng nó tất cả các thời gian dễ dàng như một sự chỉ định đơn giản, nhưng tôi chắc chắn rằng nó khá chậm hơn thế. –

+0

-1: không thực hiện bất kỳ thử nghiệm thời gian nào. –

Trả lời

8
  1. Đủ nhanh như trái ngược với những gì? Làm thế nào để bạn làm điều đó ngay bây giờ? Chính xác những gì bạn đang lưu trữ, chính xác những gì bạn đang lấy? Câu trả lời có lẽ rất phụ thuộc vào điều này. Điều này đưa chúng ta đến ...

  2. Đo lường! Đừng thảo luận và phân tích về mặt lý thuyết; hãy thử và đo lường cách thức hoạt động hiệu quả hơn. Sau đó, quyết định xem hiệu suất có thể đạt được biện minh cho việc tái cấu trúc cơ sở dữ liệu của bạn hay không.

Edit: Tôi chỉ cần chạy một kiểm tra đo chuỗi slicing so tra cứu trong một dict keyed trên (start, end) tuples. Nó cho thấy rằng không có nhiều sự khác biệt. Đó là một thử nghiệm khá ngây thơ, mặc dù vậy, hãy uống nó với một chút muối.

+1

Phương pháp hiện tại chỉ lưu trữ một văn bản, câu, và thẻ trong câu tất cả dưới dạng các chuỗi riêng biệt (trong cơ sở dữ liệu) và liên kết từng chuỗi với nhau. Có vẻ như rất nhiều sưng húp không cần thiết đối với tôi; một văn bản 2MB kết thúc lên chiếm 28mb cơ sở dữ liệu. Dù sao, những gì sẽ được lấy tất cả thời gian là câu cá nhân từ văn bản. Cách khác là cắt văn bản dựa trên các chỉ mục được lưu trữ. Nhưng bạn đã có một điểm thực sự tốt. Đo lường có lẽ là cách tốt nhất để đi. = P – tehgeekmeister

+1

Đừng đánh giá thấp phần quyết định: Nếu có sự cân bằng hiệu suất/không gian lưu trữ (và phần lớn thời gian), bạn phải tính đến tài nguyên của mình. 28mb không phải là rất nhiều nếu bạn thực sự cần thời gian CPU, nhưng có một ổ cứng terabyte theo ý của bạn. 28 mb * là * rất nhiều nếu bạn đang chạy một hệ thống nhúng nhỏ mà chỉ được truy cập một lần một ngày.Vâng, tôi đoán toàn bộ điều tôi chỉ viết nhọt xuống "Nó luôn luôn phụ thuộc" :-) – balpha

+0

@tehgeekmeister: Vui lòng cập nhật câu hỏi của bạn với những sự kiện bổ sung này. –

-1

tối ưu hóa sớm là trò lừa đảo của mọi điều ác.

Chứng minh với chính mình rằng bạn thực sự có nhu cầu tối ưu hóa mã, sau đó hành động.

1

tôi đã không thực hiện bất kỳ phép đo trong hai, nhưng vì nó có vẻ như bạn đã tham gia một cách tiếp cận C đến một vấn đề trong Python, bạn có thể muốn có một cái nhìn tại Python's built-in mmap library:

Memory- các đối tượng tệp được ánh xạ hoạt động giống như cả hai chuỗi và giống như các đối tượng tệp. Tuy nhiên, không giống như các đối tượng chuỗi bình thường, chúng có thể thay đổi được. Bạn có thể sử dụng các đối tượng mmap ở hầu hết các nơi mà các chuỗi được mong đợi; ví dụ, bạn có thể sử dụng mô-đun để tìm kiếm thông qua một tệp ánh xạ bộ nhớ. Vì chúng có thể thay đổi, bạn có thể thay đổi một ký tự đơn bằng cách thực hiện obj [index] = 'a' hoặc thay đổi chuỗi con bằng cách gán cho một lát: obj [i1: i2] = '...'. Bạn cũng có thể đọc và ghi dữ liệu bắt đầu từ vị trí tệp hiện tại và tìm kiếm() thông qua tệp đến các vị trí khác nhau.

Tôi không chắc chắn từ câu hỏi của bạn nếu đó chính xác là những gì bạn đang tìm kiếm. Và nó lặp đi lặp lại rằng bạn cần phải thực hiện một số phép đo. Python's timeit library là dễ sử dụng, nhưng cũng có cProfile hoặc hotshot, mặc dù hotshot có nguy cơ bị xóa khỏi thư viện chuẩn khi tôi hiểu nó.

3

Trong nhận xét, OP đề cập đến bloat "trong cơ sở dữ liệu" - nhưng không có thông tin về cơ sở dữ liệu mà anh ta đang nói đến; từ các thông tin nhỏ trong bình luận đó, có vẻ như các lát chuỗi Python không nhất thiết là những gì liên quan, thay vào đó, việc "cắt" sẽ được thực hiện bởi động cơ DB khi truy xuất.Nếu đó là tình hình thực tế thì tôi sẽ đề nghị các nguyên tắc chung chống lại việc lưu trữ thông tin dư thừa trong DB - một "hình thức bình thường" (có thể trong một cảm giác lỏng lẻo của biểu thức ;-) theo đó thông tin được lưu trữ chỉ một lần và có nguồn gốc thông tin được tính toán lại (hoặc phí lưu trữ của động cơ DB, vv ;-) nên là chuẩn mực, và "không chuẩn hóa" bằng cách cố ý lưu trữ thông tin có nguồn gốc rất nhiều ngoại lệ và chỉ khi được chứng minh bằng nhu cầu hiệu suất cụ thể, được đo tốt.

Nếu tham chiếu đến "cơ sở dữ liệu" là một sai lệch ;-), hoặc được sử dụng theo nghĩa lỏng lẻo như tôi đã làm cho "biểu mẫu bình thường" ở trên ;-), thì có thể áp dụng cân nhắc khác: vì chuỗi Python không thay đổi được, nó có vẻ là tự nhiên khi không phải cắt lát bằng cách sao chép, nhưng thay vì có mỗi phần tái sử dụng một phần của không gian bộ nhớ của cha mẹ nó đang được cắt từ (nhiều như được thực hiện cho các mảng mảng '). Tuy nhiên, đó không phải là một phần của lõi Python. Tôi đã từng thử một bản vá cho mục đích đó, nhưng vấn đề thêm một tham chiếu đến chuỗi lớn và do đó làm cho nó ở trong bộ nhớ chỉ vì một chuỗi con nhỏ của nó vẫn được tham chiếu rộng rãi cho thích ứng với mục đích chung. Tuy nhiên nó sẽ có thể làm cho một lớp con mục đích đặc biệt của chuỗi (và một trong unicode) cho trường hợp trong đó lớn "cha mẹ" chuỗi cần phải ở lại trong bộ nhớ anyway. Hiện tại buffer có một chút xíu, nhưng bạn không thể gọi các phương thức chuỗi trên đối tượng đệm (không rõ ràng sao chép nó vào đối tượng chuỗi đầu tiên), vì vậy nó chỉ thực sự hữu ích cho đầu ra và một vài trường hợp đặc biệt ... không có khối khái niệm thực sự chống lại phương pháp thêm chuỗi (tôi nghi ngờ rằng sẽ được thông qua trong lõi, nhưng nó nên được decently dễ dàng để duy trì như là một mô-đun bên thứ ba anyway ;-).

Giá trị của cách tiếp cận này khó có thể được chứng minh một cách chắc chắn bằng phép đo, theo cách này hay cách khác - tốc độ sẽ rất giống với phương pháp sao chép hoàn toàn hiện tại; lợi thế sẽ hoàn toàn giảm về lượng bộ nhớ, điều này sẽ không làm cho bất kỳ mã Python nào được đưa ra nhanh hơn, mà là cho phép một chương trình nào đó thực thi trên máy với RAM ít hơn một chút, hoặc nhiều tác vụ tốt hơn khi một vài trường hợp đang được sử dụng cùng một lúc trong các quy trình riêng biệt. Xem rope để có cách tiếp cận tương tự nhưng phong phú hơn khi được thử nghiệm trong ngữ cảnh của C++ (nhưng lưu ý rằng nó không làm cho nó thành tiêu chuẩn ;-).

1

Các lát cắt sẽ không hiệu quả vì chúng tạo bản sao của chuỗi nguồn không? Điều này có thể hoặc không có thể là một vấn đề. Nếu nó trở thành một vấn đề, nó sẽ không thể đơn giản thực hiện một "String xem"; một đối tượng có tham chiếu đến chuỗi nguồn và có một điểm bắt đầu và kết thúc .. Khi truy cập/lặp lại, nó chỉ đọc từ chuỗi nguồn.

+0

Đây là nỗi lo của tôi. Nhưng tôi nghĩ mọi người đều đúng: tôi không cần phải tối ưu hóa, và nếu tôi đã làm tôi nên đo đạc và kiểm tra trước khi tôi đến đây. – tehgeekmeister

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