Bộ nhớ tiến trình đọc Python Linux

Zen of Python có rất nhiều sự khôn ngoan để cung cấp. Một ý tưởng đặc biệt hữu ích là “Nên có một—và tốt nhất là chỉ một—cách rõ ràng để thực hiện. ” Tuy nhiên, có nhiều cách để làm hầu hết mọi thứ trong Python và thường là vì lý do chính đáng. Ví dụ: có nhiều cách để đọc tệp trong Python, bao gồm mô-đun

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 hiếm khi được sử dụng

Show

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 của Python cung cấp đầu vào và đầu ra tệp ánh xạ bộ nhớ (I/O). Nó cho phép bạn tận dụng chức năng của hệ điều hành cấp thấp hơn để đọc các tệp như thể chúng là một chuỗi hoặc mảng lớn. Điều này có thể mang lại những cải tiến hiệu suất đáng kể trong mã yêu cầu nhiều tệp I/O

Trong hướng dẫn này, bạn sẽ học

  • Những loại bộ nhớ máy tính tồn tại
  • Những vấn đề bạn có thể giải quyết với
    >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    1
  • Cách sử dụng ánh xạ bộ nhớ để đọc tệp lớn nhanh hơn
  • Cách thay đổi một phần của tệp mà không cần viết lại toàn bộ tệp
  • Cách sử dụng
    >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    1 để chia sẻ thông tin giữa nhiều quy trình

Tải xuống miễn phí. Nhận một chương mẫu từ CPython Internals. Hướng dẫn về Trình thông dịch Python 3 chỉ cho bạn cách mở khóa hoạt động bên trong của ngôn ngữ Python, biên dịch trình thông dịch Python từ mã nguồn và tham gia phát triển CPython

Hiểu bộ nhớ máy tính

Ánh xạ bộ nhớ là một kỹ thuật sử dụng API của hệ điều hành cấp thấp hơn để tải tệp trực tiếp vào bộ nhớ máy tính. Nó có thể cải thiện đáng kể hiệu suất I/O của tệp trong chương trình của bạn. Để hiểu rõ hơn cách ánh xạ bộ nhớ cải thiện hiệu suất, cũng như cách thức và thời điểm bạn có thể sử dụng mô-đun

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 để tận dụng các lợi ích hiệu suất này, trước tiên, bạn nên tìm hiểu một chút về bộ nhớ máy tính

Bộ nhớ máy tính là một chủ đề lớn và phức tạp, nhưng hướng dẫn này chỉ tập trung vào những gì bạn cần biết để sử dụng mô-đun

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 một cách hiệu quả. Đối với mục đích của hướng dẫn này, thuật ngữ bộ nhớ dùng để chỉ bộ nhớ truy cập ngẫu nhiên hoặc RAM

Có mấy loại bộ nhớ máy tính

  1. Thuộc vật chất
  2. Ảo
  3. chia sẻ

Mỗi loại bộ nhớ có thể phát huy tác dụng khi bạn đang sử dụng ánh xạ bộ nhớ, vì vậy hãy xem xét từng loại từ cấp độ cao

Loại bỏ các quảng cáo

Bộ nhớ vật lý

Bộ nhớ vật lý là loại bộ nhớ ít phức tạp nhất để hiểu vì nó thường là một phần của hoạt động tiếp thị liên quan đến máy tính của bạn. (Bạn có thể nhớ rằng khi bạn mua máy tính của mình, nó đã quảng cáo thứ gì đó đại loại là 8 gigabyte RAM. ) Bộ nhớ vật lý thường có trên các thẻ được kết nối với bo mạch chủ của máy tính

Bộ nhớ vật lý là dung lượng bộ nhớ dễ bay hơi có sẵn cho các chương trình của bạn sử dụng trong khi chạy. Không nên nhầm lẫn bộ nhớ vật lý với bộ lưu trữ, chẳng hạn như ổ cứng hoặc ổ cứng thể rắn của bạn

Bộ nhớ ảo

Bộ nhớ ảo là một cách xử lý quản lý bộ nhớ. Hệ điều hành sử dụng bộ nhớ ảo để làm cho bạn có vẻ như có nhiều bộ nhớ hơn thực tế, cho phép bạn bớt lo lắng về lượng bộ nhớ khả dụng cho các chương trình của mình tại bất kỳ thời điểm nào. Đằng sau hậu trường, hệ điều hành của bạn sử dụng các phần của bộ lưu trữ cố định, chẳng hạn như đĩa thể rắn, để mô phỏng RAM bổ sung

Để thực hiện việc này, hệ điều hành của bạn phải duy trì ánh xạ giữa bộ nhớ vật lý và bộ nhớ ảo. Mỗi hệ điều hành sử dụng thuật toán phức tạp của riêng mình để ánh xạ địa chỉ bộ nhớ ảo sang địa chỉ vật lý bằng cách sử dụng cấu trúc dữ liệu được gọi là bảng trang

May mắn thay, hầu hết sự phức tạp này được ẩn khỏi các chương trình của bạn. Bạn không cần phải hiểu bảng trang hoặc ánh xạ logic-to-vật lý để viết mã I/O hiệu quả bằng Python. Tuy nhiên, biết một chút về bộ nhớ sẽ giúp bạn hiểu rõ hơn về những gì máy tính và thư viện đang chăm sóc cho bạn

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 sử dụng bộ nhớ ảo để làm cho có vẻ như bạn đã tải một tệp rất lớn vào bộ nhớ, ngay cả khi nội dung của tệp quá lớn để vừa với bộ nhớ thực của bạn

Bộ nhớ dùng chung

Bộ nhớ dùng chung là một kỹ thuật khác do hệ điều hành của bạn cung cấp, cho phép nhiều chương trình truy cập đồng thời vào cùng một dữ liệu. Bộ nhớ dùng chung có thể là một cách rất hiệu quả để xử lý dữ liệu trong một chương trình sử dụng đồng thời

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 của Python sử dụng bộ nhớ dùng chung để chia sẻ hiệu quả lượng lớn dữ liệu giữa nhiều quy trình, luồng và tác vụ Python đang diễn ra đồng thời

Tìm hiểu sâu hơn về tệp I/O

Bây giờ bạn đã có một cái nhìn tổng thể về các loại bộ nhớ khác nhau, đã đến lúc hiểu ánh xạ bộ nhớ là gì và nó giải quyết những vấn đề gì. Ánh xạ bộ nhớ là một cách khác để thực hiện tệp I/O có thể mang lại hiệu suất và hiệu quả bộ nhớ tốt hơn

Để đánh giá đầy đủ chức năng của ánh xạ bộ nhớ, thật hữu ích khi xem xét I/O tệp thông thường từ góc độ cấp thấp hơn. Rất nhiều điều xảy ra đằng sau hậu trường khi đọc một tập tin

  1. Chuyển quyền kiểm soát tới mã hệ điều hành lõi hoặc hạt nhân bằng các cuộc gọi hệ thống
  2. Tương tác với đĩa vật lý nơi chứa tệp
  3. Sao chép dữ liệu vào các bộ đệm khác nhau giữa không gian người dùng và không gian kernel

Xem xét đoạn mã sau, thực hiện I/O tệp Python thông thường

________số 8

Mã này đọc toàn bộ tệp vào bộ nhớ vật lý, nếu có đủ trong thời gian chạy và in nó ra màn hình

Loại tệp I/O này là thứ bạn có thể đã học sớm trong hành trình Python của mình. Mã không dày đặc hoặc phức tạp. Tuy nhiên, những gì đang xảy ra dưới vỏ bọc của các lệnh gọi hàm như

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
9 là rất phức tạp. Hãy nhớ rằng Python là một ngôn ngữ lập trình cấp cao, rất nhiều điều phức tạp có thể bị che giấu khỏi lập trình viên

Cuộc gọi hệ thống

Trên thực tế, cuộc gọi đến

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
9 báo hiệu hệ điều hành thực hiện rất nhiều công việc phức tạp. May mắn thay, các hệ điều hành cung cấp một cách để trừu tượng hóa các chi tiết cụ thể của từng thiết bị phần cứng khỏi các chương trình của bạn bằng các lệnh gọi hệ thống. Mỗi hệ điều hành sẽ thực hiện chức năng này một cách khác nhau, nhưng ít nhất,
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
9 phải thực hiện một số lệnh gọi hệ thống để lấy dữ liệu từ tệp

Tất cả truy cập bằng phần cứng vật lý phải diễn ra trong một môi trường được bảo vệ gọi là không gian nhân. Các cuộc gọi hệ thống là API mà hệ điều hành cung cấp để cho phép chương trình của bạn chuyển từ không gian người dùng sang không gian nhân, nơi các chi tiết cấp thấp của phần cứng vật lý được quản lý

Trong trường hợp của

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
9, cần có một số lệnh gọi hệ thống để hệ điều hành tương tác với thiết bị lưu trữ vật lý và trả về dữ liệu

Một lần nữa, bạn không cần nắm vững chi tiết về các cuộc gọi hệ thống và kiến ​​trúc máy tính để hiểu được ánh xạ bộ nhớ. Điều quan trọng nhất cần nhớ là các lệnh gọi hệ thống tương đối tốn kém về mặt tính toán, vì vậy bạn càng thực hiện ít lệnh gọi hệ thống, mã của bạn sẽ có khả năng thực thi càng nhanh.

Ngoài các cuộc gọi hệ thống, cuộc gọi tới

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
9 cũng liên quan đến rất nhiều việc sao chép dữ liệu không cần thiết giữa nhiều bộ đệm dữ liệu trước khi dữ liệu quay trở lại chương trình của bạn

Thông thường, tất cả điều này xảy ra quá nhanh đến mức không đáng chú ý. Nhưng tất cả các lớp này đều tạo thêm độ trễ và có thể làm chậm chương trình của bạn. Đây là nơi ánh xạ bộ nhớ phát huy tác dụng

Loại bỏ các quảng cáo

Tối ưu hóa ánh xạ bộ nhớ

Một cách để tránh chi phí này là sử dụng tệp ánh xạ bộ nhớ. Bạn có thể hình dung việc ánh xạ bộ nhớ như một quá trình trong đó thao tác đọc và ghi bỏ qua nhiều lớp được đề cập ở trên và ánh xạ trực tiếp dữ liệu được yêu cầu vào bộ nhớ vật lý

Cách tiếp cận tệp I/O được ánh xạ bộ nhớ hy sinh việc sử dụng bộ nhớ để lấy tốc độ, được gọi một cách cổ điển là sự đánh đổi giữa không gian và thời gian. Tuy nhiên, ánh xạ bộ nhớ không phải sử dụng nhiều bộ nhớ hơn so với cách tiếp cận thông thường. Hệ điều hành rất thông minh. Nó sẽ tải dữ liệu một cách lười biếng khi được yêu cầu, tương tự như cách trình tạo Python hoạt động

Ngoài ra, nhờ bộ nhớ ảo, bạn có thể tải tệp lớn hơn bộ nhớ vật lý của mình. Tuy nhiên, bạn sẽ không thấy những cải tiến lớn về hiệu suất từ ​​ánh xạ bộ nhớ khi không có đủ bộ nhớ vật lý cho tệp của bạn, vì hệ điều hành sẽ sử dụng phương tiện lưu trữ vật lý chậm hơn như đĩa thể rắn để bắt chước bộ nhớ vật lý mà nó thiếu

Đọc tệp được ánh xạ bộ nhớ bằng Python's >>> import timeit >>> timeit.repeat( .. "regular_io(filename)", .. repeat=3, .. number=1, .. setup="from __main__ import regular_io, filename") [0.02022400000000002, 0.01988580000000001, 0.020257300000000006] >>> timeit.repeat( .. "mmap_io(filename)", .. repeat=3, .. number=1, .. setup="from __main__ import mmap_io, filename") [0.006156499999999981, 0.004843099999999989, 0.004868600000000001] 1

Bây giờ, với tất cả lý thuyết đó, bạn có thể tự hỏi mình, "Làm cách nào để sử dụng Python's

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 để tạo tệp ánh xạ bộ nhớ?"

Đây là bản đồ bộ nhớ tương đương với mã tệp I/O mà bạn đã thấy trước đây

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
6

Mã này đọc toàn bộ tệp vào bộ nhớ dưới dạng chuỗi và in nó ra màn hình, giống như cách tiếp cận trước đó với I/O tệp thông thường đã làm

Nói tóm lại, cách sử dụng

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 khá giống với cách đọc tệp truyền thống, với một vài thay đổi nhỏ

  1. Mở tệp bằng

    >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    87 là không đủ. Bạn cũng cần sử dụng
    >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    88 để báo hiệu cho hệ điều hành rằng bạn muốn tệp được ánh xạ vào RAM

  2. Bạn cần đảm bảo rằng chế độ bạn sử dụng với

    >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    87 tương thích với
    >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    88. Chế độ mặc định của
    >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    87 là để đọc, nhưng chế độ mặc định của
    >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    88 là để đọc và viết. Vì vậy, bạn sẽ phải rõ ràng khi mở tệp

  3. Bạn cần thực hiện tất cả các lần đọc và ghi bằng cách sử dụng đối tượng

    >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    1 thay vì đối tượng tệp tiêu chuẩn được trả về bởi
    >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    87

Ý nghĩa hiệu suất

Cách tiếp cận ánh xạ bộ nhớ phức tạp hơn một chút so với tệp I/O thông thường vì nó yêu cầu tạo một đối tượng khác. Tuy nhiên, sự thay đổi nhỏ đó có thể dẫn đến những lợi ích lớn về hiệu suất khi đọc một tệp chỉ vài MB. Dưới đây là so sánh về việc đọc văn bản gốc của cuốn tiểu thuyết nổi tiếng Lịch sử của Don Quixote, khoảng 2. 4 megabyte

>>>

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]

Điều này đo lượng thời gian để đọc toàn bộ 2. Tệp 4 megabyte sử dụng tệp I/O thông thường và tệp I/O được ánh xạ bộ nhớ. Như bạn có thể thấy, cách tiếp cận ánh xạ bộ nhớ mất khoảng. 005 giây so với gần như. 02 giây đối với cách tiếp cận thông thường. Cải thiện hiệu suất này có thể còn lớn hơn khi đọc một tệp lớn hơn

Ghi chú. Những kết quả này được thu thập bằng Windows 10 và Python 3. 8. Do ánh xạ bộ nhớ phụ thuộc rất nhiều vào việc triển khai hệ điều hành nên kết quả của bạn có thể thay đổi

API được cung cấp bởi đối tượng tệp

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 của Python rất giống với đối tượng tệp truyền thống ngoại trừ một siêu năng lực bổ sung. Đối tượng tệp
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 của Python có thể được cắt giống như các đối tượng chuỗi

>>> import timeit >>> timeit.repeat( .. "regular_io(filename)", .. repeat=3, .. number=1, .. setup="from __main__ import regular_io, filename") [0.02022400000000002, 0.01988580000000001, 0.020257300000000006] >>> timeit.repeat( .. "mmap_io(filename)", .. repeat=3, .. number=1, .. setup="from __main__ import mmap_io, filename") [0.006156499999999981, 0.004843099999999989, 0.004868600000000001] 1 Tạo đối tượng

Có một số điểm tinh tế trong việc tạo đối tượng

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 đáng để xem xét kỹ hơn

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
8

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 yêu cầu một bộ mô tả tệp, xuất phát từ phương thức
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
30 của một đối tượng tệp thông thường. Bộ mô tả tệp là một mã định danh bên trong, thường là số nguyên, mà hệ điều hành sử dụng để theo dõi các tệp đang mở

Đối số thứ hai của

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 là
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
32. Đây là độ dài tính bằng byte của bản đồ bộ nhớ.
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
33 là một giá trị đặc biệt cho biết rằng hệ thống sẽ tạo một bản đồ bộ nhớ đủ lớn để chứa toàn bộ tệp

Đối số

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
34 cho hệ điều hành biết cách bạn sẽ tương tác với bộ nhớ được ánh xạ. Các tùy chọn là
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
35,
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
36,
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
37 và
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
38. Chúng hơi giống với các đối số của
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
39 đối với
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
87 được tích hợp sẵn

  • >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    35 tạo bản đồ bộ nhớ chỉ đọc
  • >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    38 mặc định ở chế độ được chỉ định trong đối số
    >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    63 tùy chọn, được sử dụng để bảo vệ bộ nhớ
  • >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    36 và
    >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    37 là hai chế độ ghi mà bạn sẽ tìm hiểu bên dưới

Các đối số mô tả tệp,

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
66 và
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
34 đại diện cho mức tối thiểu bạn cần để tạo tệp ánh xạ bộ nhớ sẽ hoạt động trên các hệ điều hành như Windows, Linux và macOS. Đoạn mã trên là đa nền tảng, nghĩa là nó sẽ đọc tệp thông qua giao diện ánh xạ bộ nhớ trên tất cả các hệ điều hành mà không cần biết mã chạy trên hệ điều hành nào

Một đối số hữu ích khác là

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
68, đây có thể là một kỹ thuật tiết kiệm bộ nhớ. Điều này hướng dẫn
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 tạo bản đồ bộ nhớ bắt đầu từ một phần bù được chỉ định trong tệp

Loại bỏ các quảng cáo

>>> import timeit >>> timeit.repeat( .. "regular_io(filename)", .. repeat=3, .. number=1, .. setup="from __main__ import regular_io, filename") [0.02022400000000002, 0.01988580000000001, 0.020257300000000006] >>> timeit.repeat( .. "mmap_io(filename)", .. repeat=3, .. number=1, .. setup="from __main__ import mmap_io, filename") [0.006156499999999981, 0.004843099999999989, 0.004868600000000001] 1 Đối tượng dưới dạng Chuỗi

Như đã đề cập trước đó, ánh xạ bộ nhớ tải trong suốt nội dung tệp vào bộ nhớ dưới dạng chuỗi. Vì vậy, khi bạn mở tệp, bạn có thể thực hiện nhiều thao tác giống như bạn sử dụng với chuỗi, chẳng hạn như cắt

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
4

Mã này in mười ký tự từ

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
51 ra màn hình và cũng đọc mười ký tự đó vào bộ nhớ vật lý. Một lần nữa, dữ liệu được đọc một cách lười biếng

Lát cắt không nâng cao vị trí tệp nội bộ. Vì vậy, nếu bạn gọi

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
9 sau một lát cắt, thì bạn vẫn sẽ đọc từ đầu tệp

Tìm kiếm tệp ánh xạ bộ nhớ

Ngoài việc cắt, mô-đun

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 cho phép các hành vi giống như chuỗi khác, chẳng hạn như sử dụng
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
54 và
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
55 để tìm kiếm một tệp cho văn bản cụ thể. Ví dụ: đây là hai cách tiếp cận để tìm sự xuất hiện đầu tiên của
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
56 trong một tệp

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
3

Cả hai chức năng này đều tìm kiếm tệp cho lần xuất hiện đầu tiên của

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
56. Sự khác biệt chính giữa chúng là chức năng đầu tiên sử dụng
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
54 trên một đối tượng chuỗi, trong khi chức năng thứ hai sử dụng
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
54 trên đối tượng tệp ánh xạ bộ nhớ

Ghi chú.

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 hoạt động trên byte, không phải chuỗi

Đây là sự khác biệt về hiệu suất

>>>

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
6

Đó là một số đơn đặt hàng của sự khác biệt cường độ. Một lần nữa, kết quả của bạn có thể khác nhau tùy thuộc vào hệ điều hành của bạn

Các tệp ánh xạ bộ nhớ cũng có thể được sử dụng trực tiếp với các biểu thức chính quy. Xem xét ví dụ sau tìm và in ra tất cả các từ có năm chữ cái

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
5

Mã này đọc toàn bộ tệp và in ra mọi từ có chính xác năm chữ cái trong đó. Hãy nhớ rằng các tệp ánh xạ bộ nhớ hoạt động với các chuỗi byte, vì vậy các biểu thức chính quy cũng phải sử dụng các chuỗi byte

Đây là mã tương đương sử dụng tệp I/O thông thường

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
8

Mã này cũng in ra tất cả các từ gồm năm ký tự trong tệp, nhưng nó sử dụng cơ chế I/O tệp truyền thống thay vì các tệp ánh xạ bộ nhớ. Như trước đây, hiệu suất khác nhau giữa hai cách tiếp cận

>>>

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
9

Cách tiếp cận ánh xạ bộ nhớ vẫn nhanh hơn một bậc

Loại bỏ các quảng cáo

Các đối tượng được ánh xạ bộ nhớ dưới dạng tệp

Tệp ánh xạ bộ nhớ là một phần chuỗi và một phần tệp, vì vậy,

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 cũng cho phép bạn thực hiện các thao tác tệp phổ biến như
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
82,
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
83 và
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
84. Các chức năng này hoạt động chính xác như các đối tác tệp-đối tượng thông thường của chúng

Ví dụ: đây là cách tìm kiếm một vị trí cụ thể trong một tệp và sau đó thực hiện tìm kiếm một từ

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
60

Mã này sẽ tìm đến vị trí

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
85 trong tệp và sau đó tìm vị trí xuất hiện đầu tiên của
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
56

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
82 hoạt động hoàn toàn giống nhau trên các tệp ánh xạ bộ nhớ giống như trên các tệp thông thường

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
61

Mã cho cả hai cách tiếp cận rất giống nhau. Hãy xem hiệu suất của họ so sánh như thế nào

>>>

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
62

Một lần nữa, chỉ sau một vài điều chỉnh nhỏ đối với mã, cách tiếp cận ánh xạ bộ nhớ của bạn nhanh hơn nhiều

Viết một tệp ánh xạ bộ nhớ bằng Python's >>> import timeit >>> timeit.repeat( .. "regular_io(filename)", .. repeat=3, .. number=1, .. setup="from __main__ import regular_io, filename") [0.02022400000000002, 0.01988580000000001, 0.020257300000000006] >>> timeit.repeat( .. "mmap_io(filename)", .. repeat=3, .. number=1, .. setup="from __main__ import mmap_io, filename") [0.006156499999999981, 0.004843099999999989, 0.004868600000000001] 1

Ánh xạ bộ nhớ hữu ích nhất để đọc tệp, nhưng bạn cũng có thể sử dụng nó để ghi tệp. API

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 để ghi tệp rất giống với I/O tệp thông thường ngoại trừ một vài điểm khác biệt

Đây là một ví dụ về cách ghi văn bản vào tệp ánh xạ bộ nhớ

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
63

Mã này ghi văn bản vào tệp ánh xạ bộ nhớ. Tuy nhiên, nó sẽ đưa ra một ngoại lệ

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
90 nếu tệp trống tại thời điểm bạn tạo đối tượng
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1

Mô-đun

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 của Python không cho phép ánh xạ bộ nhớ của một tệp trống. Điều này là hợp lý bởi vì, về mặt khái niệm, một tệp ánh xạ bộ nhớ trống chỉ là một bộ đệm của bộ nhớ, do đó không cần đối tượng ánh xạ bộ nhớ

Thông thường, ánh xạ bộ nhớ được sử dụng trong chế độ đọc hoặc đọc/ghi. Ví dụ: đoạn mã sau trình bày cách đọc nhanh tệp và chỉ sửa đổi một phần của tệp

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
64

Hàm này sẽ mở một tệp đã có ít nhất mười sáu ký tự trong đó và thay đổi các ký tự 10 thành 15 thành

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
93

Các thay đổi được ghi vào

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
51 hiển thị trong tệp trên đĩa cũng như trong bộ nhớ. Tài liệu chính thức của Python khuyến nghị luôn gọi
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
95 để đảm bảo dữ liệu được ghi trở lại đĩa

Loại bỏ các quảng cáo

Chế độ ghi

Ngữ nghĩa của thao tác ghi được kiểm soát bởi tham số

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
34. Một điểm khác biệt giữa việc ghi tệp ánh xạ bộ nhớ và tệp thông thường là các tùy chọn cho tham số
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
34. Có hai tùy chọn để kiểm soát cách dữ liệu được ghi vào tệp ánh xạ bộ nhớ

  1. >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    36 chỉ định ngữ nghĩa ghi qua, nghĩa là dữ liệu sẽ được ghi qua bộ nhớ và được lưu trên đĩa
  2. >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    37 không ghi các thay đổi vào đĩa, ngay cả khi
    >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    95 được gọi

Nói cách khác,

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
36 ghi cả vào bộ nhớ và tệp, trong khi
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
37 chỉ ghi vào bộ nhớ chứ không ghi vào tệp bên dưới

Tìm kiếm và thay thế văn bản

Các tệp ánh xạ bộ nhớ hiển thị dữ liệu dưới dạng chuỗi byte, nhưng chuỗi byte đó có một lợi thế quan trọng khác so với chuỗi thông thường. Dữ liệu tệp ánh xạ bộ nhớ là một chuỗi byte có thể thay đổi. Điều này có nghĩa là việc viết mã tìm kiếm và thay thế dữ liệu trong một tệp sẽ đơn giản và hiệu quả hơn nhiều

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
65

Cả hai hàm này đều thay đổi từ

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
56 thành
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
604 trong tệp đã cho. Như bạn có thể thấy, cách tiếp cận ánh xạ bộ nhớ gần giống nhau, nhưng nó không yêu cầu theo dõi thủ công một tệp tạm thời bổ sung để thực hiện thay thế tại chỗ

Trong trường hợp này, cách tiếp cận ánh xạ bộ nhớ thực sự chậm hơn một chút đối với độ dài tệp này. Vì vậy, thực hiện tìm kiếm và thay thế đầy đủ trên tệp ánh xạ bộ nhớ có thể hoặc không phải là cách tiếp cận hiệu quả nhất. Nó có thể phụ thuộc vào nhiều thứ như độ dài tệp, tốc độ RAM của máy, v.v. Cũng có thể có một số bộ nhớ đệm của hệ điều hành làm lệch thời gian. Như bạn có thể thấy, cách tiếp cận IO thông thường đã tăng tốc trên mỗi cuộc gọi

>>>

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
66

Trong kịch bản tìm kiếm và thay thế cơ bản này, ánh xạ bộ nhớ dẫn đến mã ngắn gọn hơn một chút, nhưng không phải lúc nào cũng cải thiện tốc độ lớn. Như họ nói, “số dặm của bạn có thể thay đổi. ”

Chia sẻ dữ liệu giữa các quy trình với >>> import timeit >>> timeit.repeat( .. "regular_io(filename)", .. repeat=3, .. number=1, .. setup="from __main__ import regular_io, filename") [0.02022400000000002, 0.01988580000000001, 0.020257300000000006] >>> timeit.repeat( .. "mmap_io(filename)", .. repeat=3, .. number=1, .. setup="from __main__ import mmap_io, filename") [0.006156499999999981, 0.004843099999999989, 0.004868600000000001] 1 của Python

Cho đến bây giờ, bạn chỉ sử dụng các tệp ánh xạ bộ nhớ cho dữ liệu trên đĩa. Tuy nhiên, bạn cũng có thể tạo bản đồ bộ nhớ ẩn danh không có bộ nhớ vật lý. Điều này có thể được thực hiện bằng cách chuyển

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
606 làm bộ mô tả tệp

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
67

Điều này tạo ra một đối tượng ánh xạ bộ nhớ ẩn danh trong RAM có chứa các bản sao của

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
607 của chữ cái
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
608

Một đối tượng ánh xạ bộ nhớ ẩn danh về cơ bản là một bộ đệm có kích thước cụ thể, được chỉ định bởi tham số

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
66, trong bộ nhớ. Bộ đệm tương tự như
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
610 hoặc
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
611 từ thư viện chuẩn. Tuy nhiên, một đối tượng ánh xạ bộ nhớ ẩn danh hỗ trợ chia sẻ trên nhiều quy trình, điều mà cả
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
610 và
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
611 đều không cho phép

Điều này có nghĩa là bạn có thể sử dụng các đối tượng ánh xạ bộ nhớ ẩn danh để trao đổi dữ liệu giữa các quy trình mặc dù các quy trình có bộ nhớ và ngăn xếp hoàn toàn riêng biệt. Đây là một ví dụ về việc tạo một đối tượng ánh xạ bộ nhớ ẩn danh để chia sẻ dữ liệu có thể được ghi và đọc từ cả hai quy trình

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
68

Với đoạn mã này, bạn tạo một bộ đệm được ánh xạ bộ nhớ của

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
607 byte và cho phép bộ đệm đó được đọc và ghi từ cả hai quy trình. Cách tiếp cận này có thể hữu ích nếu bạn muốn tiết kiệm bộ nhớ và vẫn chia sẻ một lượng lớn dữ liệu trên nhiều quy trình

Chia sẻ bộ nhớ với ánh xạ bộ nhớ có một số lợi thế

  • Dữ liệu không phải được sao chép giữa các quy trình
  • Hệ điều hành xử lý bộ nhớ trong suốt
  • Dữ liệu không cần phải được chọn giữa các quy trình, giúp tiết kiệm thời gian của CPU

Nói về việc tẩy, cần chỉ ra rằng

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 không tương thích với các API cấp cao hơn, đầy đủ tính năng hơn như mô-đun
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
616 tích hợp. Mô-đun
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
616 yêu cầu dữ liệu được truyền giữa các quy trình để hỗ trợ giao thức pickle, điều mà
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 không có

Bạn có thể muốn sử dụng

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
616 thay vì
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
620, như sau

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
69

Tại đây, bạn cố gắng tạo một quy trình mới và chuyển nó vào bộ đệm ánh xạ bộ nhớ. Đoạn mã này sẽ ngay lập tức tăng giá trị

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
621 vì đối tượng
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 không thể được chọn, đối tượng này được yêu cầu để chuyển dữ liệu sang quy trình thứ hai. Vì vậy, để chia sẻ dữ liệu với ánh xạ bộ nhớ, bạn sẽ cần sử dụng
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
620 cấp thấp hơn

Nếu bạn đang sử dụng Python 3. 8 trở lên, thì bạn có thể sử dụng mô-đun

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
624 mới để chia sẻ dữ liệu hiệu quả hơn trên các quy trình Python

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
0

Chương trình nhỏ này tạo một danh sách gồm 1607 ký tự và sửa đổi 50 ký tự đầu tiên từ một quy trình khác

Chỉ lưu ý tên của bộ đệm được chuyển đến quy trình thứ hai. Sau đó, quá trình thứ hai có thể truy xuất cùng một khối bộ nhớ đó bằng tên duy nhất. Đây là một tính năng đặc biệt của mô-đun

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
624 được cung cấp bởi
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1. Về cơ bản, mô-đun
>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
624 sử dụng API duy nhất của mỗi hệ điều hành để tạo bản đồ bộ nhớ được đặt tên cho bạn

Bây giờ bạn đã biết một số chi tiết triển khai cơ bản của bộ nhớ dùng chung mới Python 3. 8 tính năng cũng như cách sử dụng trực tiếp

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1

Loại bỏ các quảng cáo

Phần kết luận

Ánh xạ bộ nhớ là một cách tiếp cận khác đối với tệp I/O có sẵn cho các chương trình Python thông qua mô-đun

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1. Ánh xạ bộ nhớ sử dụng API hệ điều hành cấp thấp hơn để lưu trữ nội dung tệp trực tiếp trong bộ nhớ vật lý. Cách tiếp cận này thường dẫn đến hiệu suất I/O được cải thiện vì nó tránh được nhiều cuộc gọi hệ thống tốn kém và giảm chuyển bộ đệm dữ liệu tốn kém

Trong hướng dẫn này, bạn đã học

  • Sự khác biệt giữa bộ nhớ vật lý, ảo và chia sẻ là gì
  • Cách tối ưu hóa việc sử dụng bộ nhớ với ánh xạ bộ nhớ
  • Cách sử dụng mô-đun
    >>> import timeit
    >>> timeit.repeat(
    ..     "regular_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import regular_io, filename")
    [0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
    >>> timeit.repeat(
    ..     "mmap_io(filename)",
    ..     repeat=3,
    ..     number=1,
    ..     setup="from __main__ import mmap_io, filename")
    [0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
    
    1 của Python để triển khai ánh xạ bộ nhớ trong mã của bạn

API

>>> import timeit
>>> timeit.repeat(
..     "regular_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import regular_io, filename")
[0.02022400000000002, 0.01988580000000001, 0.020257300000000006]
>>> timeit.repeat(
..     "mmap_io(filename)",
..     repeat=3,
..     number=1,
..     setup="from __main__ import mmap_io, filename")
[0.006156499999999981, 0.004843099999999989, 0.004868600000000001]
1 tương tự như API tệp I/O thông thường, do đó, việc kiểm tra khá đơn giản. Hãy thử mã của riêng bạn để xem liệu chương trình của bạn có thể hưởng lợi từ những cải tiến hiệu suất do ánh xạ bộ nhớ mang lại hay không

Đánh dấu là đã hoàn thành

Xem ngay Hướng dẫn này có một khóa học video liên quan do nhóm Real Python tạo. Xem nó cùng với hướng dẫn bằng văn bản để hiểu sâu hơn. bản đồ Python. Thực hiện I/O tệp với ánh xạ bộ nhớ

🐍 Thủ thuật Python 💌

Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python

Bộ nhớ tiến trình đọc Python Linux

Gửi cho tôi thủ thuật Python »

Giới thiệu về Luke Lee

Bộ nhớ tiến trình đọc Python Linux
Bộ nhớ tiến trình đọc Python Linux

Luke đã viết phần mềm chuyên nghiệp cho các ứng dụng từ ứng dụng web và máy tính để bàn Python đến trình điều khiển C nhúng cho Ổ đĩa thể rắn. Anh ấy cũng đã phát biểu tại PyCon, PyTexas, PyArkansas, PyconDE và các nhóm gặp gỡ

» Thông tin thêm về Lu-ca


Mỗi hướng dẫn tại Real Python được tạo bởi một nhóm các nhà phát triển để nó đáp ứng các tiêu chuẩn chất lượng cao của chúng tôi. Các thành viên trong nhóm đã làm việc trong hướng dẫn này là

Bộ nhớ tiến trình đọc Python Linux

Aldren

Bộ nhớ tiến trình đọc Python Linux

Brad

Bộ nhớ tiến trình đọc Python Linux

Geir Arne

Bộ nhớ tiến trình đọc Python Linux

Joanna

Bộ nhớ tiến trình đọc Python Linux

Gia-cốp

Bậc thầy Kỹ năng Python trong thế giới thực Với quyền truy cập không giới hạn vào Python thực

Bộ nhớ tiến trình đọc Python Linux

Tham gia với chúng tôi và có quyền truy cập vào hàng nghìn hướng dẫn, khóa học video thực hành và cộng đồng các Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Bậc thầy Kỹ năng Python trong thế giới thực
Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng ngàn hướng dẫn, khóa học video thực hành và cộng đồng Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Bạn nghĩ sao?

Đánh giá bài viết này

Tweet Chia sẻ Chia sẻ Email

Bài học số 1 hoặc điều yêu thích mà bạn đã học được là gì?

Mẹo bình luận. Những nhận xét hữu ích nhất là những nhận xét được viết với mục đích học hỏi hoặc giúp đỡ các sinh viên khác. Nhận các mẹo để đặt câu hỏi hay và nhận câu trả lời cho các câu hỏi phổ biến trong cổng thông tin hỗ trợ của chúng tôi

Bạn có thể đọc bộ nhớ bằng Python không?

Lớp ReadWriteMemory được tạo trên Python để đọc và ghi vào bộ nhớ của bất kỳ tiến trình nào . Lớp này không phụ thuộc vào bất kỳ mô-đun bổ sung nào và chỉ sử dụng các thư viện Python tiêu chuẩn như ctypes.

Làm cách nào để kiểm tra bộ nhớ được mã Python sử dụng?

Làm việc với Python Memory Profiler . Bạn sẽ thấy mức sử dụng bộ nhớ theo từng dòng sau khi tập lệnh của bạn thoát. putting the @profile decorator around any function or method and running python -m memory_profiler myscript. You'll see line-by-line memory usage once your script exits.

Tập lệnh Python sử dụng bao nhiêu bộ nhớ?

Những số đó có thể dễ dàng khớp với số nguyên 64 bit, vì vậy người ta hy vọng Python sẽ lưu trữ một triệu số nguyên đó trong không quá ~8MB. một triệu đối tượng 8 byte. Trên thực tế, Python sử dụng nhiều hơn như 35 MB RAM để lưu trữ những con số này. Tại sao? .

Một tiến trình có thể truy cập bộ nhớ tiến trình khác không?

Về nguyên tắc, các quy trình không thể truy cập vào bộ nhớ của các quy trình khác . Trong thực tế, hệ điều hành cơ bản thường cung cấp cơ chế này cho các quy trình đặc quyền.