পাইথনের গতি বাড়ানোর কিছু উপায়

পাইথন, সাম্প্রতিক সময়ের একটি জনপ্রিয় প্রোগ্রামিং ল্যাঙ্গুয়েজ। সহজবোধ্য সিনট্যাক্স আর সমৃদ্ধ লাইব্রেরী থাকায় কম্পিটিটিভ প্রোগ্রামিংয়েও এর ব্যবহার বাড়ছে। অধিকাংশ ছেলেমেয়েরা পাইথন দিয়ে প্রোগ্রামিং শেখা শুরু করে। প্রথম প্রথম সবকিছু সহজে চললেও কঠিন সমস্যাগুলো সমাধান করার সময় পাইথন ব্যবহার করতে গিয়ে তারা  Time Limit Exceeded  রেজাল্ট পায়। এটা অবশ্য পাইথনের দোষ না, সল্ভারের দোষ। সল্ভার যদি ইফিশিয়েন্ট কোড লেখে, তবে তা  Accepted  হতে বাধ্য। কিন্তু পাইথন আসলেই একটু স্লো। যে সমস্যা সি/সি++ এর নেইভ সলুশন দিয়ে ১ সেকেন্ড টাইম লিমিটে করা যায় সেই একই নেইভ সলুশন পাইথন দিয়ে 5x টাইমেও করা যায় না (আমার একটা পাইথন কোড এর জলজ্যান্ত প্রমাণ!)। তবে কিছু ট্রিকস ব্যবহার করে কম্পিটিটিভ প্রোগ্রামিংয়ে পাইথনকে একটু ফাস্ট করে এর অ্যাডভান্টেজ নেয়া সম্ভব। এ নিয়েই আজকে আলোচনা করছি।

যথাযথ ডাটা স্ট্রাকচার ব্যবহার করা

পাইথনে এই ব্যপারটা তার রানটাইমের ওপর ব্যাপক প্রভাব ফেলে। পাইথনে বিল্ট ইন ভাবে লিস্ট, টাপল, সেট এবং ডিকশনারি ডাটা স্ট্রাকচার আছে (অন্যান্য মডিউলে আরো আছে)। কিন্তু আমি সবাইকে দেখি, যেকোনো ডাটা রাখার জন্য পাইথনের লিস্ট ব্যবহার করে। যেটা একেবারে কাম্য নয়। যেখানে যে ডাটা স্ট্রাকচার ব্যবহার করলে ভালো হয়, সেখানে সে ডাটা স্ট্রাকচারই ব্যবহার করা উচিত। বিশেষ করে লিস্টের পরিবর্তে টাপল ব্যবহার করা উচিত। কারণ টাপলের ওপর ইটারেট করতে লিস্টের চেয়ে কম সময় লাগে (তবে টাপলের কোনো ইলিমেন্ট পরিবর্তন করা যায় না এই ব্যাপারটা মাথায় রাখতে হবে)।

যথাসম্ভব ফর লুপ পরিহার করা

পাইথনের ফর লুপ ডাইনামিক হওয়ার কারণে ফর লুপ ব্যবহার করলে সময় বেশি লাগে। তাই যেখানে ফর লুপ না ব্যবহার করে হোয়াইল লুপ দিয়েই কাজ সারা যায় সেখানে হোয়াইল লুপ ই ব্যবহার করা উচিত।

লিস্ট কম্প্রিহেনশন ব্যবহার করা

যেখানে লিস্ট কম্প্রিহেনশন ব্যবহার করা যাবে সেখানে অন্য উপায়ে করা বোকামি ছাড়া কিছু না। যেমনঃ 1 থেকে 100000 পর্যন্ত সকল 3 দ্বারা বিভাজ্য সংখ্যার লিস্ট বানাতে হলে অধিকাংশরাই এভাবে করবে:

l = []
for i in range(1, 100000):
    if i%3 == 0:
        l.append(i)

তবে উচিত হবে এভাবে লিস্ট কম্প্রিহেনশন ব্যবহার করা:

l = [i for i in range(1, 100000) if i%3 == 0]

অ্যাপেন্ড করার চেয়ে লিস্ট কম্প্রিহেনশন খুবই ফাস্ট কাজ করে। আর এতে কোড শর্টও হয়।

মাল্টিপল অ্যাসাইনমেন্ট ব্যবহার করা

a = 2
b = 3
c = 5
d = 7

এভাবে আলাদা আলাদা করে একাধিক ভেরিয়েবল অ্যাসাইন না করে মাল্টিপল অ্যাসাইনমেন্ট করলে সময়ও কম লাগে আর কোডও শর্ট হয়। ঠিক এভাবে:

a, b, c, d = 2, 3, 5, 7

গ্লোবাল ভেরিয়েবল পরিহার করা

পাইথনের global কিওয়ার্ড ব্যবহার করে গ্লোবাল ভেরিয়েবল ডিক্লেয়ার করা যায় এটা তো জানাই আছে। কিন্তু পাইথন গ্লোবাল ভেরিয়েবলের অপারেশনে বেশি সময় নেয় (লোকাল ভেরিয়েবলের তুলনায়)। তাই প্রয়োজন না হলে পাইথনে গ্লোবাল ভেরিয়েবল ব্যবহার করা উচিত নয়।

লাইব্রেরী ফাংশন ব্যবহার করা

পাইথনের জনপ্রিয় হওয়ার বড় একটা কারণ ই হলো এর বিশাল সমৃদ্ধ লাইব্রেরী। এর লাইব্রেরীতে অসংখ্য গুরুত্বপূর্ণ ফাংশন রয়েছে। যারা কোনো একটা ফাংশন সম্পর্কে জানে না তারা ঐ ফাংশনের জন্য ম্যানুয়ালি কোড লেখে। কিন্তু যতই হাই কোয়ালিটি + ইফিশিয়েন্ট ফাংশন লেখা হোক না কেন তা ঐ লাইব্রেরী ফাংশনের চেয়ে দ্রুত এবং মেমোরি সাশ্রয়ী হবে না। তাই লাইব্রেরী ফাংশনগুলো সম্পর্কে ভালো ধারণা রাখতে হবে।

জেনারেটর ব্যবহার করা

আমাদের যদি একটা বিশাল বড় লিস্ট থাকে আর ঐ লিস্টের প্রতিটা উপাদানকে নিয়ে মাত্র এবং কেবলমাত্র একবার কাজ করতে হয় তবে আমাদের উচিত একটা জেনারেটর অবজেক্ট নিয়ে ঐ কাজটা করা। এটা বিরাট বড় একটা সময় বাঁচিয়ে দেবে।

ইনফিনিটি লুপের কন্ডিশন হিসেবে 1 ব্যবহার করা

অনেকে ইনফিনিটি লুপ লেখে এভাবে:

while True:
    # statements

কিন্তু এভাবে না করে নিচের মতো করে করলে সামান্য একটু দ্রুত কাজ হয়। যখন প্রোগ্রামে অনেকগুলো ইনফিনিটি লুপ থাকে তখন এটা খুব কাজে দেয়।

while 1:
    # statements

যাহা ইফিশিয়েন্ট মনে হয় তাহা সবসময় ইফিশিয়েন্ট নয়

বলা হলো একটা বিরাট বড় বাগানে অনেকগুলো গাছ আছে। গাছগুলোর লিস্ট দেয়া থাকবে। এরপর একটা গাছের নাম দিয়ে জিজ্ঞেস করা হবে গাছটা ঐ লিস্টে আছে কি না? তো কিছু ‘প্রো’ এইভাবে কোড লিখবে:

trees = [ ...tree_names... ]
tree = input()
if tree in set(trees):
    ...

সবার মনে হচ্ছে, ঠিক ই তো করেছে। যেহেতু trees লিস্টটাকে সেট এ কনভার্ট করা হয়েছে তাই কন্ডিশনটা খুব তাড়াতাড়ি এক্সিকিউট করবে। কিন্তু সবাই বুঝে না যে ঐ সেট এ কনভার্ট করার জন্যেও একটা নির্দিষ্ট সময় লাগে। অর্থাৎ সবার চোখে এটা ইফিশিয়েন্ট হলেও আদতে এটা ইফিশিয়েন্ট না। তার চেয়ে এভাবে করলেই কম সময় লাগে:

if tree in trees:
    ...

পাইথনের স্পিডআপ অ্যাপলিকেশন ব্যবহার করা

পাইথনের রানটাইমকে ফাস্ট করার জন্য হাতে নেয়া হয়েছে বেশ কয়েকটি প্রোজেক্ট। যার মধ্যে PyPy এবং Numba অন্যতম। তবে প্রায় প্রতিটি কনটেস্ট যেখানে পাইথন ব্যবহার করতে দেয়া হয় সেখানে PyPy ল্যাঙ্গুয়েজ হিসেবে দেয়া থাকে। তাই উচিত হলো পাইথনকে ল্যাঙ্গুয়েজ হিসেবে না সিলেক্ট করে PyPy কে সিলেক্ট করে সাবমিট করা।

তো এইরকম কিছু টিপস আর ট্রিকস ব্যবহার করে আমরা আমাদের পাইথন কোডকে করে তুলতে পারি আরো বেশি ইফিশিয়েন্ট, যা কম্পিটিটিভ প্রোগ্রামিংয়ে পাইথন ব্যবহার করার সময় একটু বেশি অ্যাডভান্টেজ দেবে। আরো অনেক টিপস রয়েছে, যার বেশিরভাগই কম্পিটিটিভ প্রোগ্রামিংয়ের জন্য নয়। তবুও দেখতে সমস্যা কি!

মন্তব্যসমূহ

এই ব্লগটি থেকে জনপ্রিয় পোস্টগুলি

উইন্ডোজ পিসি থেকে কোনো সফটওয়্যার পুরোপুরি আনইন্সটল করার নিয়ম

উইন্ডোজ পিসির গতি বৃদ্ধি করার উপায়

কম্পিটিটিভ প্রোগ্রামিংয়ের দুনিয়ায় প্রবেশের গল্প