পাইথন কী এমন কোনও পরিবর্তনশীলকে অপ্টিমাইজ করে যা কেবলমাত্র ফেরতের মান হিসাবে ব্যবহৃত হয়?


106

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

পাইথন কি তাদের সমতুল্য বাইটোকোডে পরিণত করে? তাদের মধ্যে একটি দ্রুত?

কেস 1 :

def func():
    a = 42
    return a

কেস 2 :

def func():
    return 42

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

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

উত্তর:


138

না, তা হয় না

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

আসলে কী ঘটতে চলেছে তা একবার disদেখার জন্য * উত্পাদিত নির্দেশিকা দেখতে * ব্যবহার করুন । প্রথম কার্যের জন্য, অ্যাসাইনমেন্টটি সহ:

from dis import dis
dis(func)
  2           0 LOAD_CONST               1 (42)
              2 STORE_FAST               0 (a)

  3           4 LOAD_FAST                0 (a)
              6 RETURN_VALUE

দ্বিতীয় কার্যের জন্য:

dis(func2)
  2           0 LOAD_CONST               1 (42)
              2 RETURN_VALUE

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

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

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

* disএকটি অল্প পাইথন মডিউল যা আপনার কোডটি ডিস-এসেম্বল করে, আপনি পাইথন বাইকোড যা ভিএম চালিত করবে তা দেখতে আপনি এটি ব্যবহার করতে পারেন।

দ্রষ্টব্য: @ জর্ন ভার্নির একটি মন্তব্যে যেমন বলা হয়েছে, এটি পাইথনের সিপিথন বাস্তবায়নের জন্য সুনির্দিষ্ট। অন্যান্য বাস্তবায়নগুলি যদি তারা ইচ্ছা করে তবে আরও আক্রমণাত্মক অনুকূলকরণ করতে পারে, সিপিথন এটি না করে।


11
পাইথন ব্যক্তি নয় (সি ++) তাই আমি জানি না এটি কীভাবে হুডের নীচে কাজ করে তবে প্রথম কেসটি দ্বিতীয় কেসে অনুকূলিত হওয়া উচিত নয়? একটি শালীন সি ++ সংকলক সেই অপ্টিমাইজেশন তৈরি করবে।
নাথান অলিভার

7
@ নাথান ওলিভার এটি সত্যিই না করে, পাইথন এটি এখানে স্মার্টভাবে চালানোর চেষ্টা না করেই এখানে যেমন বলেছে তা করবে।
দিমিত্রিস ফাসারাকিস হিলিয়ার্ড

80
এই প্রশ্নের উত্তরে @ নাথান ওলিভারের যথাযথ যুক্তিসঙ্গত এবং বুদ্ধিমান অনুমান যে সত্যটি সম্পূর্ণ ভুল তা আমার দৃষ্টিতে প্রমাণ হয় যে এটি কোনও "স্ব-ব্যাখ্যামূলক", "বাজে", "বোকা" প্রশ্ন নয় যা উত্তর দেওয়া যেতে পারে টাইগারহকটি 3 হিসাবে আমাদের "বিশ্বাস করার জন্য একটি মুহুর্ত নেওয়া" দ্বারা। এটি একটি বৈধ, আকর্ষণীয় প্রশ্ন যা আমি বহু বছর ধরে পাইথন প্রোগ্রামার পেশাদার হয়েও তার উত্তর সম্পর্কে নিশ্চিত নই।
মার্ক

পাইথনের সংকলক সেরা 'রক্ষণশীল', 'খুব রক্ষণশীল' নয়। মূল নকশার লক্ষ্যটি "যত তাড়াতাড়ি দ্রুত হওয়া উচিত ... তাই আপনি একটি সংকলন পর্ব বিদ্যমান বলেও লক্ষ্য করেন না।" এটি মাধ্যমিক, "এটিকে সহজ রাখুন" এর পরে। "1 << (2 ** 34)" এবং "বি'এক্স '* (2 ** 32)" এর মতো বৃহত ধ্রুবক সহ একটি ফাংশন সংকলন করতে কয়েক সেকেন্ড সময় নেয় এবং জিবি-আকারের ধ্রুবক তৈরি করে, এমনকি যদি ফাংশনটি কখনও না হয় তবে চালানো। সংকলক দ্বারা এমনকি বড় স্ট্রিং ফেলে দেওয়া হবে। এই ক্ষেত্রেগুলির প্রস্তাবিত ফিক্সগুলি প্রত্যাখ্যান করা হয়েছে কারণ তারা সংকলকটিকে আরও জটিল করে তুলবে।
অ্যান্ড্রু ডাল্ক 22:57

@ অ্যান্ড্রুডালকে এ সম্পর্কে অভ্যন্তরীণ মন্তব্যের জন্য ধন্যবাদ, আপনি যে বিষয়গুলি দেখিয়েছেন সেগুলি সমাধান করার জন্য আমি এই শব্দটি টিক দিয়েছি।
দিমিত্রিস ফাসারাকিস হিলিয়ার্ড

3

উভয়ই মূলত একই, ব্যতীত প্রথম ক্ষেত্রে অবজেক্টটি 42কেবল নাম পরিবর্তিত একটি ভেরিয়েবলের সাথে সংযুক্ত করা হয় aবা অন্য কথায় নাম (অর্থাত্ a) মানগুলি (যেমন 42) বোঝায় । এটি প্রযুক্তিগতভাবে কোনও অ্যাসাইনমেন্ট করে না, এই অর্থে যে এটি কখনই কোনও ডেটা অনুলিপি করে না।

আইএনগ returnকরার সময় , এই নামকরণ করা বাধ্যতামূলকটি aপ্রথম ক্ষেত্রে 42ফিরে আসে এবং দ্বিতীয় ক্ষেত্রে বস্তুটি ফিরে আসে।

আরও পড়ার জন্য, নেড ব্যাচেল্ডারের এই দুর্দান্ত নিবন্ধটি দেখুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.