আরও ভালো পারফরম্যান্সের জন্য আপনার পাইথন স্ক্রিপ্টগুলি কীভাবে অপ্টিমাইজ করবেন

Ara O Bhalo Parapharamyansera Jan Ya Apanara Pa Ithana Skriptaguli Kibhabe Aptima Ija Karabena



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

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

  1. অ্যাপ্লিকেশনের কর্মক্ষমতা বুস্ট করুন
  2. পঠনযোগ্য এবং সংগঠিত কোড তৈরি করুন
  3. ত্রুটি পর্যবেক্ষণ এবং ডিবাগিং সহজ করুন
  4. যথেষ্ট গণনা শক্তি সংরক্ষণ করুন এবং তাই ঘোষণা

আপনার কোড প্রোফাইল

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







টুকিটাকি সংকেতলিপি:



আমদানি cProfile হিসাবে সিপি
ডিফ সমষ্টি গণনা করুন ( ইনপুট নম্বর ) :
যোগফল_অফ_ইনপুট_সংখ্যা = 0
যখন ইনপুট নম্বর > 0 :
যোগফল_ইনপুট_সংখ্যা + = ইনপুট সংখ্যা % 10
ইনপুট নম্বর // = 10
ছাপা ( 'ইনপুট নম্বরের সমস্ত অঙ্কের যোগফল হল: 'sum_of_input_numbers'' )
ফিরে যোগফল_অফ_ইনপুট_সংখ্যা
ডিফ main_func ( ) :
সিপি চালান ( 'calculateSum(9876543789)' )
যদি __নাম__ == '__প্রধান__' :
main_func ( )

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



অতিরিক্তভাবে, প্রোগ্রামটি প্রম্পট স্ক্রিনে একটি প্রতিবেদন প্রিন্ট করে যা দেখায় যে প্রোগ্রামটি 0.000 সেকেন্ডের মধ্যে তার সমস্ত কার্য সম্পাদনের সময় শেষ করে। এই প্রোগ্রাম কত দ্রুত দেখায়.





সঠিক ডেটা স্ট্রাকচার বেছে নিন

কর্মক্ষমতা বৈশিষ্ট্য ডেটা কাঠামোর উপর নির্ভরশীল। বিশেষ করে, অভিধানগুলি সাধারণ-উদ্দেশ্য সঞ্চয়স্থান সম্পর্কিত তালিকাগুলির চেয়ে দ্রুত অনুসন্ধানের জন্য। আপনি যদি জানেন যে আমরা আপনার ডেটাতে যে ক্রিয়াকলাপগুলি পরিচালনা করব তার জন্য সবচেয়ে উপযুক্ত ডেটা কাঠামো নির্বাচন করুন৷ নিম্নলিখিত উদাহরণটি ডেটা স্ট্রাকচারে একটি উপাদান উপস্থিত আছে কিনা তা নির্ধারণ করতে একটি অভিন্ন প্রক্রিয়ার জন্য বিভিন্ন ডেটা স্ট্রাকচারের কার্যকারিতা তদন্ত করে।



প্রতিটি ডাটা স্ট্রাকচার-একটি তালিকা, একটি সেট এবং একটি অভিধানে একটি উপাদান উপস্থিত আছে কিনা তা পরীক্ষা করতে যে সময় লাগে তা আমরা মূল্যায়ন করি এবং তাদের তুলনা করি।

OptimizeDataType.py:

আমদানি টাইমি হিসাবে tt
আমদানি এলোমেলো হিসাবে rndobj
# পূর্ণসংখ্যার একটি তালিকা তৈরি করুন
এলোমেলো_ডেটা_তালিকা = [ rndobj. রেন্ডিন্ট ( 1 , 10000 ) জন্য _ ভিতরে পরিসীমা ( 10000 ) ]
# একই ডেটা থেকে একটি সেট তৈরি করুন
এলোমেলো_ডেটা_সেট = সেট ( এলোমেলো_ডেটা_তালিকা )

# কী হিসাবে একই ডেটা দিয়ে একটি অভিধান তৈরি করুন
obj_DataDictionary = { একের উপর: কোনোটিই নয় জন্য একের উপর ভিতরে এলোমেলো_ডেটা_তালিকা }

# অনুসন্ধান করার জন্য উপাদান (ডেটাতে বিদ্যমান)
এলোমেলো_সংখ্যা_খুঁজে = rndobj. পছন্দ ( এলোমেলো_ডেটা_তালিকা )

# একটি তালিকায় সদস্যতা পরীক্ষা করার সময় পরিমাপ করুন
তালিকা_সময় = tt টাইমি ( ল্যাম্বডা : random_number_to_find ভিতরে এলোমেলো_ডেটা_তালিকা , সংখ্যা = 1000 )

# একটি সেটে সদস্যতা পরীক্ষা করার সময় পরিমাপ করুন
সেট সময় = tt টাইমি ( ল্যাম্বডা : random_number_to_find ভিতরে এলোমেলো_ডেটা_সেট , সংখ্যা = 1000 )

# একটি অভিধানে সদস্যতা পরীক্ষা করার সময় পরিমাপ করুন
dict_time = tt টাইমি ( ল্যাম্বডা : random_number_to_find ভিতরে obj_DataDictionary , সংখ্যা = 1000 )

ছাপা ( 'তালিকা সদস্যতা যাচাইয়ের সময়: {list_time:.6f} সেকেন্ড' )
ছাপা ( 'সদস্যতা যাচাইয়ের সময় সেট করুন: {set_time:.6f} সেকেন্ড' )
ছাপা ( 'অভিধান সদস্যতা পরীক্ষা করার সময়: {dict_time:.6f} সেকেন্ড' )

সদস্যতা পরীক্ষা করার সময় এই কোড তালিকা, সেট এবং অভিধানের কার্যকারিতা তুলনা করে। সাধারণভাবে, সেট এবং অভিধানগুলি সদস্যতা পরীক্ষার জন্য তালিকার তুলনায় যথেষ্ট দ্রুত কারণ তারা হ্যাশ-ভিত্তিক লুকআপ ব্যবহার করে, তাই তাদের O(1) এর গড় সময় জটিলতা রয়েছে। অন্যদিকে, তালিকাগুলিকে অবশ্যই রৈখিক অনুসন্ধানগুলি করতে হবে যা O(n) সময় জটিলতার সাথে সদস্যতার পরীক্ষায় পরিণত হয়।

  একটি কম্পিউটার বর্ণনার একটি স্ক্রিন শট স্বয়ংক্রিয়ভাবে তৈরি হয়

লুপের পরিবর্তে বিল্ট-ইন ফাংশন ব্যবহার করুন

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

সাধারণ কাজের জন্য বিল্ট-ইন ফাংশন ব্যবহার করে কাস্টম লুপ তৈরির পারফরম্যান্সের তুলনা করার জন্য কিছু নমুনা কোড তৈরি করা যাক (যেমন মানচিত্র(), ফিল্টার(), এবং সাজানো())। বিভিন্ন ম্যাপিং, পরিস্রাবণ এবং বাছাই পদ্ধতিগুলি কতটা ভাল কাজ করে তা আমরা মূল্যায়ন করব।

BuiltInFunctions.py:

আমদানি টাইমি হিসাবে tt
# নম্বর_তালিকার নমুনা তালিকা
সংখ্যার_তালিকা = তালিকা ( পরিসীমা ( 1 , 10000 ) )

# একটি লুপ ব্যবহার করে বর্গ সংখ্যা_তালিকায় ফাংশন
ডিফ বর্গাকার_ব্যবহারের_লুপ ( সংখ্যার_তালিকা ) :
বর্গ_ফল = [ ]
জন্য একের উপর ভিতরে সংখ্যা_তালিকা:
বর্গ_ফল। সংযোজন ( একের উপর ** 2 )
ফিরে বর্গ_ফল
# একটি লুপ ব্যবহার করে জোড় সংখ্যা_তালিকা ফিল্টার করার ফাংশন
ডিফ filter_even_using_loop ( সংখ্যার_তালিকা ) :
ফিল্টার_ফলাফল = [ ]
জন্য একের উপর ভিতরে সংখ্যা_তালিকা:
যদি একের উপর % 2 == 0 :
ফিল্টার_ফলাফল। সংযোজন ( একের উপর )
ফিরে ফিল্টার_ফলাফল
# একটি লুপ ব্যবহার করে নম্বর_তালিকা সাজানোর ফাংশন
ডিফ sort_using_loop ( সংখ্যার_তালিকা ) :
ফিরে সাজানো ( সংখ্যার_তালিকা )
# মানচিত্র() ব্যবহার করে বর্গ সংখ্যা_তালিকার সময় পরিমাপ করুন
মানচিত্র_সময় = tt টাইমি ( ল্যাম্বডা : তালিকা ( মানচিত্র ( ল্যাম্বডা x: x ** 2 , সংখ্যার_তালিকা ) ) , সংখ্যা = 1000 )
# ফিল্টার() ব্যবহার করে জোড় সংখ্যা_তালিকা ফিল্টার করার সময় পরিমাপ করুন
ফিল্টার_টাইম = tt টাইমি ( ল্যাম্বডা : তালিকা ( ছাঁকনি ( ল্যাম্বডা x: x % 2 == 0 , সংখ্যার_তালিকা ) ) , সংখ্যা = 1000 )
# sorted() ব্যবহার করে সংখ্যা_তালিকা সাজানোর সময় পরিমাপ করুন
সাজানো_সময় = tt টাইমি ( ল্যাম্বডা : সাজানো ( সংখ্যার_তালিকা ) , সংখ্যা = 1000 )
# একটি লুপ ব্যবহার করে বর্গ সংখ্যা_তালিকার সময় পরিমাপ করুন
লুপ_ম্যাপ_টাইম = tt টাইমি ( ল্যাম্বডা : বর্গাকার_ব্যবহারের_লুপ ( সংখ্যার_তালিকা ) , সংখ্যা = 1000 )
# একটি লুপ ব্যবহার করে জোড় সংখ্যা_তালিকা ফিল্টার করার সময় পরিমাপ করুন
লুপ_ফিল্টার_টাইম = tt টাইমি ( ল্যাম্বডা : filter_even_using_loop ( সংখ্যার_তালিকা ) , সংখ্যা = 1000 )
# একটি লুপ ব্যবহার করে সংখ্যা_তালিকা সাজানোর সময় পরিমাপ করুন
loop_sorted_time = tt টাইমি ( ল্যাম্বডা : sort_using_loop ( সংখ্যার_তালিকা ) , সংখ্যা = 1000 )
ছাপা ( 'সংখ্যার তালিকায় 10000টি উপাদান রয়েছে' )
ছাপা ( 'মানচিত্র() সময়: {map_time:.6f} সেকেন্ড' )
ছাপা ( 'ফিল্টার() সময়: {filter_time:.6f} সেকেন্ড' )
ছাপা ( 'Sorted() সময়: {sorted_time:.6f} সেকেন্ড' )
ছাপা ( 'লুপ (মানচিত্র) সময়: {loop_map_time:.6f} সেকেন্ড' )
ছাপা ( 'লুপ (ফিল্টার) সময়: {loop_filter_time:.6f} সেকেন্ড' )
ছাপা ( 'লুপ (বাছাই করা) সময়: {loop_sorted_time:.6f} সেকেন্ড' )

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

লুপগুলি অপ্টিমাইজ করুন

যদি লুপগুলি লেখার প্রয়োজন হয়, তবে কয়েকটি কৌশল রয়েছে যা আমরা তাদের গতি বাড়ানোর জন্য করতে পারি। সাধারণত, range() লুপটি পিছিয়ে যাওয়ার চেয়ে দ্রুত হয়। এর কারণ হল range() তালিকাটি উল্টে না দিয়ে একটি পুনরাবৃত্তিকারী তৈরি করে যা দীর্ঘ তালিকার জন্য একটি ব্যয়বহুল অপারেশন হতে পারে। উপরন্তু, যেহেতু range() মেমরিতে একটি নতুন তালিকা তৈরি করে না, এটি কম মেমরি ব্যবহার করে।

OptimizeLoop.py:

আমদানি টাইমি হিসাবে tt
# নম্বর_তালিকার নমুনা তালিকা
সংখ্যার_তালিকা = তালিকা ( পরিসীমা ( 1 , 100000 ) )
# বিপরীত ক্রমে তালিকার উপর পুনরাবৃত্তি করার ফাংশন
ডিফ loop_reverse_iteration ( ) :
ফলাফল_বিপরীত = [ ]
জন্য j ভিতরে পরিসীমা ( কেবল ( সংখ্যার_তালিকা ) - 1 , - 1 , - 1 ) :
ফলাফল_বিপরীত। সংযোজন ( সংখ্যার_তালিকা [ j ] )
ফিরে ফলাফল_বিপরীত
# রেঞ্জ() ব্যবহার করে তালিকার উপর পুনরাবৃত্তি করার ফাংশন
ডিফ লুপ_রেঞ্জ_পুনরাবৃত্তি ( ) :
ফলাফল_পরিসীমা = [ ]
জন্য k ভিতরে পরিসীমা ( কেবল ( সংখ্যার_তালিকা ) ) :
ফলাফল_পরিসীমা সংযোজন ( সংখ্যার_তালিকা [ k ] )
ফিরে ফলাফল_পরিসীমা
# বিপরীত পুনরাবৃত্তি সঞ্চালন করার সময় পরিমাপ করুন
বিপরীত_সময় = tt টাইমি ( loop_reverse_iteration , সংখ্যা = 1000 )
# পরিসরের পুনরাবৃত্তি করতে যে সময় লাগে তা পরিমাপ করুন
পরিসীমা_সময় = tt টাইমি ( লুপ_রেঞ্জ_পুনরাবৃত্তি , সংখ্যা = 1000 )
ছাপা ( 'নম্বর তালিকায় 100000 রেকর্ড রয়েছে' )
ছাপা ( 'বিপরীত পুনরাবৃত্তির সময়: {reverse_time:.6f} সেকেন্ড' )
ছাপা ( 'পরিসীমা পুনরাবৃত্তির সময়: {range_time:.6f} সেকেন্ড' )

অপ্রয়োজনীয় ফাংশন কল এড়িয়ে চলুন

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

প্রোফাইলিংয়ের জন্য সরঞ্জাম

আপনার কোডের পারফরম্যান্স সম্পর্কে আরও জানতে, বিল্ট-ইন প্রোফাইলিং ছাড়াও, আমরা cProfile, Pyflame, বা SnakeViz এর মতো বাহ্যিক প্রোফাইলিং প্যাকেজগুলি ব্যবহার করতে পারি।

ক্যাশে ফলাফল

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

কোড রিফ্যাক্টরিং

কোড রিফ্যাক্টর করা সহজ করে পড়া এবং বজায় রাখা কখনও কখনও এটি অপ্টিমাইজ করার একটি প্রয়োজনীয় অংশ। একটি দ্রুত প্রোগ্রাম এছাড়াও পরিষ্কার হতে পারে.

জাস্ট-ইন-টাইম কম্পাইলেশন (JIT) ব্যবহার করুন

PyPy বা Numba এর মত লাইব্রেরিগুলি একটি JIT সংকলন প্রদান করতে পারে যা উল্লেখযোগ্যভাবে নির্দিষ্ট ধরণের Python কোডের গতি বাড়াতে পারে।

পাইথন আপগ্রেড করুন

নিশ্চিত করুন যে আপনি পাইথনের সর্বশেষ সংস্করণ ব্যবহার করছেন কারণ নতুন সংস্করণগুলিতে প্রায়শই কর্মক্ষমতা উন্নতি অন্তর্ভুক্ত থাকে।

সমান্তরালতা এবং সামঞ্জস্য

সমান্তরাল করা যেতে পারে এমন প্রক্রিয়াগুলির জন্য, মাল্টিপ্রসেসিং, থ্রেডিং বা অ্যাসিনসিওর মতো সমান্তরাল এবং সিঙ্ক্রোনাইজেশন কৌশলগুলি তদন্ত করুন।

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

উপসংহার

উপসংহারে, উন্নত কর্মক্ষমতা এবং সম্পদ কার্যকারিতার জন্য পাইথন কোড অপ্টিমাইজেশন অত্যন্ত গুরুত্বপূর্ণ। ডেভেলপাররা বিভিন্ন কৌশল ব্যবহার করে তাদের পাইথন অ্যাপ্লিকেশানগুলির কার্য সম্পাদনের গতি এবং প্রতিক্রিয়াশীলতাকে ব্যাপকভাবে বৃদ্ধি করতে পারে যেমন উপযুক্ত ডেটা স্ট্রাকচার নির্বাচন করা, অন্তর্নির্মিত ফাংশনগুলিকে ব্যবহার করা, অতিরিক্ত লুপগুলি হ্রাস করা এবং কার্যকরভাবে মেমরি পরিচালনা করা। ক্রমাগত বেঞ্চমার্কিং এবং প্রোফাইলিং অপ্টিমাইজেশন প্রচেষ্টাকে নির্দেশ করতে হবে, নিশ্চিত করে যে কোড অগ্রগতি বাস্তব-বিশ্বের কর্মক্ষমতা প্রয়োজনীয়তার সাথে মেলে। একটি দীর্ঘমেয়াদী প্রকল্পের সাফল্যের গ্যারান্টি এবং নতুন সমস্যা প্রবর্তনের সম্ভাবনা কমাতে, কোডটি অপ্টিমাইজ করা ক্রমাগত কোড পাঠযোগ্যতা এবং রক্ষণাবেক্ষণযোগ্যতার উদ্দেশ্যগুলির সাথে ভারসাম্যপূর্ণ হওয়া উচিত।