কম্পিউটার টিউটোরিয়াল

পাইথনে MMAP ফাংশন ব্যবহার করে ফাইল রিডিং পারফরম্যান্স উন্নত করা

ভূমিকা

MMAP বা মেমরি ম্যাপিং যখন একটি ফাইলের সাথে ম্যাপ করা হয়, তবে অপারেটিং সিস্টেমের ভার্চুয়াল মেমরি ব্যবহার করে ফাইল সিস্টেমের ডেটা সরাসরি অ্যাক্সেস করে, সাধারণ I/O ফাংশন ব্যবহারের পরিবর্তে। ফলে I/O পারফরম্যান্স উন্নত হয় কারণ প্রতিটি অ্যাক্সেসের জন্য আলাদা সিস্টেম কল করতে হয় না বা বাফারের মধ্যে ডেটা কপি করতে হয় না।

যেকোনো কিছু মেমরিতে থাকলে (যেমন ইন-মেমরি SQLite ডাটাবেস) ডিস্কের চেয়ে ভালো পারফরম্যান্স দেয়।

মেমরি-ম্যাপড ফাইলগুলো পরিবর্তনশীল স্ট্রিং বা ফাইল-লাইক অবজেক্ট হিসেবে বিবেচনা করা যায়।

MMAP অনেক মেথড সাপোর্ট করে: close(), flush(), read(), readline(), seek(), tell(), write() এবং স্লাইস অপারেশন ও রেগুলার এক্সপ্রেশনেও ভালো কাজ করে।

কীভাবে করবেন

১. টেক্সট ফাইল তৈরি

নিচের কন্টেন্ট সহ একটি input.txt ফাইল তৈরি করুন।

২. mmap() ফাংশন ব্যবহার করে মেমরি-ম্যাপড ফাইল তৈরি

ফাইলনেম fileno() মেথড বা os.open() থেকে পাস করা যায়।

নোট: ইউজার ফাইল খুলতে এবং বন্ধ করতে দায়বদ্ধ।

mmap()-র দ্বিতীয় আর্গুমেন্ট হল বাইটে সাইজ, কতটুকু ফাইল ম্যাপ করা হবে। ০ দিলে পুরো ফাইল ম্যাপ হয়। এছাড়া ACCESS_READ (রিড-অনলি), ACCESS_WRITE (রাইট-থ্রু), ACCESS_COPY (কপি-অন-রাইট) অ্যাক্সেস মোড আছে।

import mmap
input_text = """Lorem ipsum dolor sit amet..."""
# ইনপুট ফাইল তৈরি
input_file = 'input.txt'
f = open(input_file, "w+")
f.write(input_text)
f.close()

# রিড মোডে ফাইল খুলুন
with open(input_file, 'r') as f:
    with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as m:
        print(f"Output \n*** Output first 5 bytes of the {input_file} is {m.read(5)} ")
        print(f"*** Output Next 10 bytes of the {input_file} is {m.read(10)} ")

আউটপুট

*** Output first 5 bytes of the input.txt is b'Lorem'
*** Output Next 10 bytes of the input.txt is b' ipsum dol'

৩. ফাইল পয়েন্টার मूভমেন্ট

প্রথমে ৫ বাইট পড়া হলে ফাইল পয়েন্টার ১০ বাইট আগে চলে যায়। আবার read(10) করলে ৬-১৫ বাইট পাওয়া যায়।

৪. মেমরি ম্যাপড ফাইল আপডেট করার জন্য সেটআপ

আপডেটের জন্য 'r+' মোডে ফাইল খুলুন ( 'w' নয়)।

উদাহরণ: একটি লাইনের অংশ ইন-প্লেস মডিফাই করা।

import mmap
import shutil
input_file = 'input.txt'
input_copy = input_file.replace('input','input_copy')
# কপি বানান যাতে অরিজিনাল অপরিবর্তিত থাকে
shutil.copyfile(input_file, input_copy)

word = b'ipsum'
modified_word = word[::-1]  # উল্টা করুন

with open(input_copy, 'r+') as f:
    with mmap.mmap(f.fileno(), 0) as m:
        print(f"output \n *** Line before updates \n {m.readline().rstrip()}")
        m.seek(0)
        loc = m.find(word)
        m[loc:loc + len(word)] = modified_word
        m.flush()
        m.seek(0)
        print(f" \n *** Line after updates \n {m.readline().rstrip()}")
    f.seek(0)
    print(f" \n *** Final file \n {f.readline().rstrip()}")

আউটপুট

*** Line before updates b'Lorem ipsum dolor sit amet...'
*** Line after updates b'Lorem muspi dolor sit amet...'
*** Final file Lorem muspi dolor sit amet...

শব্দ "ipsum" মেমরিতে এবং ফাইলের মাঝপথে রিপ্লেস হয়েছে।

৫. শুধু ইন-মেমরি পরিবর্তন (ACCESS_COPY)

যদি ডিস্কে আপডেট না চান, শুধু মেমরিতে পরিবর্তন দেখতে চান, তবে ACCESS_COPY ব্যবহার করুন।

with open(input_copy, 'r+') as f:
    with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_COPY) as m:
        # ... একই লজিক ...
        # ফাইনাল ফাইল দেখাবে অরিজিনাল কন্টেন্ট

আউটপুট

*** Line after updates b'Lorem muspi dolor sit amet...'
*** Final file Lorem ipsum dolor sit amet...

নিশ্চিত হয়েছে যে ডিস্কে ফাইল অপরিবর্তিত রয়েছে, শুধু মেমরিতে পরিবর্তন হয়েছে।

  1. নতুন ফাইল সিস্টেম (File System) দিয়ে উইন্ডোজ পারফরম্যান্স উন্নত করার পদ্ধতি

  2. Python-এ def দিয়ে সংজ্ঞায়িত ফাংশন প্লট করার পদ্ধতি? (Matplotlib)

  3. পাইথনে ZIPFILE মডিউল ব্যবহার করে ফাইল কম্প্রেস করা

  4. পাইথন Tkinter-এ asksaveasfile() ফাংশন