ফাংশন কতটুকু প্রভাবকে কার্যকারিতা বলে?


13

পদ্ধতি বা ফাংশনগুলিতে কার্যকারিতা এক্সট্রাক্ট করা কোডের মড্যুলারিটি, পঠনযোগ্যতা এবং আন্তঃব্যবহারযোগ্যতার জন্য বিশেষত ওওপি-তে প্রয়োজনীয়।

তবে এর অর্থ আরও ফাংশন কল করা হবে।

কীভাবে আমাদের কোডগুলি পদ্ধতি বা ফাংশনে বিভক্ত করা আধুনিক আধুনিক ভাষাগুলিতে কার্য সম্পাদনকে প্রভাবিত করে?

* সর্বাধিক জনপ্রিয়: সি, জাভা, সি ++, সি #, পাইথন, জাভাস্ক্রিপ্ট, রুবি ...



1
আমি মনে করি, এর লবণের প্রতিটি ভাষার প্রয়োগ এখন বেশ কয়েক দশক ধরে ইনলাইন করছে। আইওডাব্লু, ওভারহেডটি অবশ্যই অবিকল 0
জার্গ ডব্লু মিট্যাগ 10'16

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

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

1
প্রভাবটি যদি কোনও হয় তবে এটি খুব কম যে আপনি, কোনও ব্যক্তি কখনও তা লক্ষ্য করবেন না। চিন্তার মতো আরও অনেক গুরুত্বপূর্ণ বিষয় রয়েছে। ট্যাবগুলি 5 বা 7 স্পেসের হওয়া উচিত কিনা তা পছন্দ করুন।
মেটাফাইট

উত্তর:


21

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

void DoSomething()
{
   a = a + 1;
   DoSomethingElse(a);
}

void DoSomethingElse(int a)
{
   b = a + 3;
}

সংকলক ইনলাইন করার সিদ্ধান্ত নিয়েছে DoSomethingElseএবং কোডটি হয়ে যায়

void DoSomething()
{
   a = a + 1;
   b = a + 3;
}

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

ফাংশন কলগুলি (প্ল্যাটফর্মের উপর নির্ভর করে) সাধারণত কয়েকটি 10s নির্দেশাবলী জড়িত থাকে এবং এর মধ্যে স্ট্যাকটি সংরক্ষণ / পুনরুদ্ধার করা অন্তর্ভুক্ত। কিছু ফাংশন কলগুলিতে একটি লাফ এবং রিটার্ন নির্দেশ থাকে।

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

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


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

1
আমি এটিতে পিগি-ব্যাক করব এবং বলব যে ওপির অকাল অপটিমাইজেশন
প্যাট্রিক

1
@ পেট্রিক বিঙ্গো আপনি যদি অপ্টিমাইজ করতে চলেছেন তবে ধীর বিভাগগুলি কোথায় রয়েছে তা দেখতে প্রোফাইলার ব্যবহার করুন। অনুমান করবেন না। ধীরে ধীরে বিভাগগুলি যেখানে থাকতে পারে তার জন্য আপনি সাধারণত অনুভূতি পেতে পারেন তবে এটি কোনও প্রোফাইলারের মাধ্যমে নিশ্চিত করুন।
CHendrix

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

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

5

এটি সংকলক বা রানটাইম বাস্তবায়নের বিষয় (এবং এর বিকল্পগুলি) এবং কোনও নির্দিষ্টতা দিয়ে বলা যায় না।

সি এবং সি ++ এর মধ্যে কিছু সংকলক অপ্টিমাইজেশন সেটিংসের উপর ভিত্তি করে কলগুলিকে ইনলাইন করবে - https://gcc.godbolt.org/ এর মতো সরঞ্জামগুলি দেখার সময় উত্পন্ন সমাবেশটি পরীক্ষা করার মাধ্যমে এটি তুচ্ছভাবে দেখা যায় can

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

-XX:InlineSmallCode=n পূর্ববর্তী সংকলিত পদ্ধতিটি কেবল তখনই ইনলাইন করুন যদি এর উত্পন্ন দেশীয় কোডের আকারটি এর চেয়ে কম হয়। জেভিএম যে প্ল্যাটফর্মটিতে চলছে তার সাথে ডিফল্ট মান পরিবর্তিত হয়।
-XX:MaxInlineSize=35 অন্তর্ভুক্ত করার জন্য কোনও পদ্ধতির সর্বাধিক বাইকোড আকার।
-XX:FreqInlineSize=n ইনলাইন হওয়ার জন্য প্রায়শই সম্পাদিত পদ্ধতির সর্বাধিক বাইকোড আকার। জেভিএম যে প্ল্যাটফর্মটিতে চলছে তার সাথে ডিফল্ট মান পরিবর্তিত হয়।

হ্যাঁ, হটস্পট জেআইটি সংকলক নির্দিষ্ট মানদণ্ডগুলি পূরণ করে এমন পদ্ধতিগুলিকে ইনলাইন করবে।

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

এটি সিপথন ইনলাইনিংয়ের সাথে নয়, তবে জাইথন ​​(জেভিএম-তে চলছে পাইথন) কিছু কল in অনুরূপভাবে এমআরআই রুবি ইনলাইনিংয়ের সময় জেআরবি যাবেন না, এবং রুবি 2 সি যা রুবিতে সি তে রূপান্তরকারী ... যা তখন সংকলিত সি সংকলক বিকল্পগুলির উপর নির্ভর করে ইনলাইনিং বা নাও হতে পারে।

ভাষাগুলি ইনলাইন করে না। বাস্তবায়ন হতে পারে


5

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

এটি একটি ফাংশন একটি ক্রেডিট কার্ড মত হয়। যেহেতু আপনি সহজেই এটি ব্যবহার করতে পারেন, তাই আপনার এটির চেয়ে বেশি ব্যবহার করার প্রবণতা রয়েছে। মনে করুন আপনি এটির প্রয়োজনের তুলনায় 20% বেশি কল করেছেন। তারপরে, টিপিক্যাল বৃহত সফ্টওয়্যারটিতে কয়েকটি স্তর থাকে যা প্রতিটি কলিং ফাংশন নীচের স্তরে থাকে, সুতরাং ১.২ এর ফ্যাক্টর স্তরগুলির সংখ্যার সাথে আরও জটিল হতে পারে। (উদাহরণস্বরূপ, যদি পাঁচটি স্তর থাকে এবং প্রতিটি স্তরের 1.2 এর ধীরগতির ফ্যাক্টর থাকে তবে সংশ্লেষিত ধীরগতির কারণটি 1.2 ^ 5 বা 2.5 হয়।) এটি সম্পর্কে চিন্তা করার এক উপায় এটি।

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

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

while(!JobDone(idJob)){
    ...
}

অথবা

foreach(idJob in jobs){
    if (JobDone(idJob)){
        ...
    }
}

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


1

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

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

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

কিন্তু

আপনি যখন ফাংশনের অভ্যন্তরে ভেরিয়েবলগুলি সংজ্ঞায়িত করেন, দোভাষী আপনার কোডটি আরও দ্রুত করে তোলে, বাইটকোডে সাধারণ LOAD নির্দেশের পরিবর্তে LOADFST ব্যবহার করে ...

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

আমি মনে করি যে আপনার প্রশ্নের বাস্তবে স্ট্যাকেক্সচেঞ্জের পুরো উত্তর দেওয়া খুব বিস্তৃত।

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

আপনি এই প্রক্রিয়াতে কতগুলি জিনিস শিখবেন তা শুনে আপনি অবাক হবেন।

আপনার যদি কোনও নির্দিষ্ট সমস্যা থাকে তবে পরিমাপ / প্রোফাইল তৈরি করুন এবং আবহাওয়া স্থির করুন কোনও ফাংশন তৈরি করা বা সমতুল্য কোডটি অনুলিপি / আটকানো ভাল।

আপনি যদি আরও নির্দিষ্ট প্রশ্ন জিজ্ঞাসা করেন তবে আরও নির্দিষ্ট উত্তর পাওয়া আরও সহজ হবে বলে আমি মনে করি।


আপনাকে উদ্ধৃত করে: "আমি মনে করি যে আপনার প্রশ্নের বাস্তবে স্ট্যাকেক্সচেঞ্জের পুরো উত্তর দেওয়া খুব বিস্তৃত" " তখন আমি কীভাবে এটিকে সংকুচিত করব? আমি পারফরম্যান্সে ফাংশন কল প্রভাবকে উপস্থাপন করে এমন কিছু আসল তথ্য দেখতে চাই love আমি কোন ভাষায় পাত্তা দিচ্ছি না, আমি আরও বিস্তারিত ব্যাখ্যা দেখার কৌতূহল বোধ করছি, সম্ভব হলে ডেটা ব্যাক আপ করে রেখেছি, যেমনটা আমি বলেছি।
দাদাবাবা

মুল বক্তব্যটি এটি ভাষার উপর নির্ভর করে। সি এবং C ++, যদি ফাংশন inlined হয়, প্রভাব 0. তাহলে inlined নয়, এটা তার পরামিতি দ্বারা নির্ভর করে যদি এটা ক্যাশের মধ্যে না বা ইত্যাদি ...
ingframin

1

কিছুক্ষণ আগে জেনন পাওয়ারপিসিতে সরাসরি এবং ভার্চুয়াল সি ++ ফাংশন কলগুলির ওভারহেড পরিমাপ করেছি

প্রশ্নযুক্ত ফাংশনগুলির একটি একক প্যারামিটার এবং একটি একক রিটার্ন ছিল, সুতরাং প্যারামিটার পাসিং রেজিস্টারে ঘটে।

দীর্ঘ গল্প সংক্ষেপে, একটি ইনলাইন ফাংশন কলের তুলনায় ডাইরেক্ট (নন-ভার্চুয়াল) ফাংশন কলের ওভারহেড ছিল প্রায় 5.5 ন্যানোসেকেন্ড বা 18 ঘড়ির চক্র। ভার্চুয়াল ফাংশন কলের ওভারহেডটি ইনলাইনের তুলনায় 13.2 ন্যানোসেকেন্ড বা 42 ক্লকচক্র ছিল।

এই সময়গুলি বিভিন্ন প্রসেসর পরিবারের ক্ষেত্রে সম্ভবত আলাদা। আমার পরীক্ষার কোড এখানে ; আপনি আপনার হার্ডওয়্যার এ একই পরীক্ষা চালাতে পারেন। মত একটি উচ্চ স্পষ্টতা টাইমার ব্যবহার করুন rdtsc আপনার CFastTimer বাস্তবায়নের; সিস্টেম সময় () প্রায় যথেষ্ট সুনির্দিষ্ট নয়।

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