কর্মক্ষমতা উন্নত করতে আপনি কোন সাধারণ কৌশল ব্যবহার করেন?


21

আপনার কোডটি পড়া আরও শক্ত না করে পারফরম্যান্সের উন্নতির জন্য আমরা যেভাবে সাধারণ রুটিনগুলি লিখি সে সম্পর্কে আমি বলছি ... উদাহরণস্বরূপ, এটি আমাদের শিখার জন্য আদর্শ:

for(int i = 0; i < collection.length(); i++ ){
   // stuff here
}

তবে, সাধারণত যখন foreachএটি প্রযোজ্য না হয় তখন আমি এটি করি :

for(int i = 0, j = collection.length(); i < j; i++ ){
   // stuff here
}

আমি মনে করি এটি একটি আরও ভাল পদ্ধতির কারণ এটি lengthএকবারে পদ্ধতিটিকে কল করবে ... আমার বান্ধবী জানায় এটি রহস্যজনক। আপনি নিজের উন্নতিতে ব্যবহার করেন এমন অন্য কোনও সাধারণ কৌশল আছে?


34
আপনার বান্ধবীর স্পষ্ট না হলে আপনাকে এমন একজন বান্ধবী থাকার জন্য +1 করুন।
ক্রিস্টো

76
আপনার শুধু আমাদের একটি বান্ধবী আছে তা জানানোর জন্য আপনি এই পোস্ট করছেন।
জোশ কে ২

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

5
@ টমউইজ: সঠিক (এবং সম্পূর্ণ) উক্তি: "আমাদের ছোট কার্যকারিতা সম্পর্কে ভুলে যাওয়া উচিত, সময়ের প্রায় 97% বলুন: অকাল অনুকূলকরণ সমস্ত মন্দের মূল Yet তবুও আমাদের এই সমালোচনামূলক 3% তে আমাদের সুযোগগুলি অতিক্রম করা উচিত নয়। "
রবার্ট হার্ভে

3
@ টমভিজ: আপনি যদি তিন শতাংশ ব্যয় করে থাকেন তবে সংজ্ঞা অনুসারে আপনার এটি সময়-সমালোচনামূলক কোডে করা উচিত, এবং অন্যান্য %৯% আপনার সময় নষ্ট না করে।
রবার্ট হার্ভে

উত্তর:


28

অকাল-আলোচনা সন্নিবেশ করান-সমস্ত-অশুভ বক্তৃতা-এর-মূল-মূল

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

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

আপনার বিগ-ও জানুন

এটি সম্ভবত উপরের দীর্ঘ আলোচনায় মার্জ করা উচিত। এটি বেশ সাধারণ জ্ঞান যে একটি লুপের ভিতরে একটি লুপ, যেখানে অভ্যন্তরীণ লুপটি গণনার পুনরাবৃত্তি করে, এটি ধীর হয়ে যায়। উদাহরণ স্বরূপ:

for (i = 0; i < strlen(str); i++) {
    ...
}

স্ট্রিংটি সত্যিই দীর্ঘ হলে এটি একটি ভয়াবহ সময় গ্রহণ করবে, কারণ লুপটির প্রতিটি পুনরাবৃত্তিতে দৈর্ঘ্যটি পুনঃ গণনা করা হচ্ছে। নোট করুন যে জিসিসি প্রকৃতপক্ষে এই কেসটিকে অনুকূল করে কারণ strlen()একটি খাঁটি ফাংশন হিসাবে চিহ্নিত রয়েছে।

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

একইভাবে, ডাটাবেসগুলির সাথে কাজ করার সময় সূচী সম্পর্কে সচেতন হন। যদি আপনার SELECT * FROM people WHERE age = 20এবং আপনার লোকের (বয়স) কোনও সূচক না থাকে তবে এটির জন্য খুব দ্রুত ও (লগ এন) সূচক স্ক্যানের চেয়ে ও (এন) অনুক্রমিক স্ক্যানের প্রয়োজন হবে।

পূর্ণসংখ্যার গাণিতিক শ্রেণিবিন্যাস

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

  • + - ~ & | ^
  • << >>
  • *
  • /

মঞ্জুর, সংকলকটি সাধারণত আপনি মূলধারার কম্পিউটারটিকে টার্গেট n / 2করা থাকলে n >> 1স্বয়ংক্রিয়ভাবে পছন্দ করার মতো জিনিসগুলি অনুকূল করে তুলবেন তবে আপনি যদি এমবেডেড ডিভাইসটিকে লক্ষ্য করে দেখছেন তবে আপনি সেই বিলাসিতা পাবেন না।

এছাড়াও, % 2এবং & 1বিভিন্ন শব্দার্থবিজ্ঞান আছে। বিভাগ এবং মডুলাস সাধারণত শূন্যের দিকে ঘুরতে থাকে তবে এটি বাস্তবায়ন সংজ্ঞায়িত হয়। ভাল ওল ' >>এবং &সর্বদা নেতিবাচক অনন্তের দিকে ঘোরা, যা (আমার মতে) অনেক বেশি অর্থবোধ করে। উদাহরণস্বরূপ, আমার কম্পিউটারে:

printf("%d\n", -1 % 2); // -1 (maybe)
printf("%d\n", -1 & 1); // 1

অতএব, বোঝার জন্য ব্যবহার করুন। আপনি % 2যখন লিখতে যাবেন ঠিক তখন ব্যবহার করে আপনি ভাল ছেলে হবেন না & 1

ব্যয়বহুল ভাসমান পয়েন্ট অপারেশন

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

int parseInt(const char *str)
{
    const char *p;
    int         digits;
    int         number;
    int         position;

    // Count the number of digits
    for (p = str; isdigit(*p); p++)
        {}
    digits = p - str;

    // Sum the digits, multiplying them by their respective power of 10.
    number = 0;
    position = digits - 1;
    for (p = str; isdigit(*p); p++, position--)
        number += (*p - '0') * pow(10, position);

    return number;
}

এই ব্যবহারটি কেবল pow()(এবং int<-> doubleরূপান্তরগুলি ব্যবহার করার প্রয়োজন) নয় কেবল ব্যয়বহুল, তবে এটি নির্ভুল ক্ষতির জন্য একটি সুযোগ তৈরি করে (ঘটনাক্রমে, উপরের কোডটিতে যথাযথ সমস্যা নেই)। এই কারণেই আমি যখন গাণিতিক প্রসঙ্গে ব্যবহৃত এই ধরণের ফাংশনটি দেখি w

এছাড়াও লক্ষ্য করুন যে নীচের "চালাক" অ্যালগরিদমটি যা প্রতিটি পুনরাবৃত্তিতে 10 দ্বারা গুণিত হয়, উপরের কোডের তুলনায় আসলে আরও সংক্ষিপ্ত:

int parseInt(const char *str)
{
    const char *p;
    int         number;

    number = 0;
    for (p = str; isdigit(*p); p++) {
        number *= 10;
        number += *p - '0';
    }

    return number;
}

খুব পুঙ্খানুপুঙ্খ উত্তর।
প্যাডিস্ল্যাকার

1
দ্রষ্টব্য, অকাল অপটিমাইজেশন আলোচনা আবর্জনা কোডের জন্য প্রযোজ্য নয়। আপনার সর্বদা প্রথম স্থানে কাজ করে একটি বাস্তবায়ন ব্যবহার করা উচিত।

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

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

আপনি ঠিক বলেছেন, আমার ভুল, এবং আমার ডাবল-চেক করা উচিত। দু'জনের মধ্যে সূক্ষ্ম পার্থক্যের কারণে আমি তোতাপাখির প্রকল্পটিতে কাজ করে যাচ্ছি pureবা constএটি হিসাবে শিরোনাম ফাইলে নথিবদ্ধ করেছি। docs.parrot.org/parrot/1.3.0/html/docs/dev/c_funitions.pod.html
অ্যান্ডি লেস্টার

13

আপনার প্রশ্ন এবং মন্তব্য থ্রেড থেকে, আপনার "মনে হয়" মনে হচ্ছে যে এই কোড পরিবর্তনটি কার্যকারিতা উন্নত করে, তবে তা বাস্তবায়ন করে কি না আপনি সত্যই জানেন না।

আমি কেন্ট বেকের দর্শনের ভক্ত :

"এটিকে কাজ করুন, এটিকে সঠিক করুন, দ্রুত করুন" "

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

উদাহরণস্বরূপ, .NET কোড দিয়ে গতি পরীক্ষা করার জন্য আমি NUnit এর টাইমআউট বৈশিষ্ট্যটি লিখতে একটি নির্দিষ্ট পদ্ধতিতে একটি কল নির্দিষ্ট সময়ের মধ্যে সঞ্চালিত করব তা লিখতে ব্যবহার করি ।

আপনি যে কোড উদাহরণ দিয়েছেন (এবং লুপের জন্য একটি বৃহত সংখ্যক পুনরুক্তি) রয়েছে তার সাথে নুনিতের টাইম আউট অ্যাট্রিবিউট জাতীয় কিছু ব্যবহার করে আপনি কোডটিতে আপনার "উন্নতি" সত্যিই সেই লুপটির পারফরম্যান্সে সহায়তা করেছিলেন কিনা তা প্রমাণ করতে পারতেন।

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


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

ইউনিট পরীক্ষার জন্য অগত্যা প্রয়োজন হয় না, তবে কিছু পারফরম্যান্সের মিথটি সত্য কিনা তা পরীক্ষা করতে এই 20 মিনিট ব্যয় করা সর্বদা সার্থক হয়, বিশেষত কারণ উত্তরটি প্রায়শই সংকলক এবং -O এবং -g পতাকার অবস্থার উপর নির্ভর করে (বা ডিবাগ / ভিএস ক্ষেত্রে মুক্তি)।
এমবিকিউ

+1 এই উত্তরটি প্রশ্নের সাথে আমার সম্পর্কিত মন্তব্যকে পরিপূরক করে।
তামারা উইজসম্যান

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

@ শ্যাশিলি অবশ্যই যদি আপনি দুটি সমানভাবে পাঠযোগ্য পদ্ধতি সম্পর্কে চিন্তা করতে পারেন এবং আপনি যে কম দক্ষতার জন্য বেছে নিচ্ছেন আপনি কেবল নিজের কাজ করছেন না? কেউ কি আসলে তা করতে পারে?
glenatron

11

মনে রাখবেন যে আপনার সংকলকটি ভাল করে উঠতে পারে:

for(int i = 0; i < collection.length(); i++ ){
   // stuff here
}

মধ্যে:

int j = collection.length();
for(int i = 0; i < j; i++ ){
   // stuff here
}

বা অনুরূপ কিছু, যদি collectionলুপের উপরে অপরিবর্তিত থাকে।

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

এটি আপনাকে এই কয়েকটি অতিরিক্ত মেশিন চক্র অর্জন করার সময় কোডটির পঠনযোগ্যতা বজায় রাখবে (যেমনটি বেশিরভাগ লোকেরা প্রত্যাশা করে। তারপরে আপনি অন্যান্য ক্ষেত্রগুলিতে মনোনিবেশ করতে পারেন যেখানে সংকলক আপনাকে সহায়তা করতে পারে না।

একদিকে নোট: আপনি যদি collectionউপাদানগুলি যোগ করে বা মুছে ফেলার মাধ্যমে লুপটির ভিতরে পরিবর্তন করেন (হ্যাঁ, আমি জানি এটি একটি খারাপ ধারণা, তবে এটি ঘটে) তবে আপনার দ্বিতীয় উদাহরণটি হয় সমস্ত উপাদানকে ছাড়িয়ে যাবে না বা অতীতকে অ্যাক্সেস করার চেষ্টা করবে অ্যারের সমাপ্তি


1
কেন শুধু এটি স্পষ্টভাবে না?

3
কিছু ভাষায় যা সীমাবদ্ধ-চেক করে, আপনি যদি আপনার কোডটি স্পষ্টভাবে করেন তবে আপনি আপনার কোডটি স্লুড করবেন। সংগ্রহের জন্য একটি লুপের সাথে the দৈর্ঘ্যের সংকলকটি এটি আপনার জন্য সরিয়ে নিয়ে যায় এবং সীমা পরীক্ষাটি বাদ দেয়। আপনার অ্যাপ্লিকেশন অন্য কোথাও থেকে কিছু ধ্রুবক একটি লুপ সঙ্গে আপনার প্রতিটি পুনরাবৃত্তি পরীক্ষা করতে হবে। এজন্য এটি পরিমাপ করা জরুরী - পারফরম্যান্স সম্পর্কে অন্তর্দৃষ্টি প্রায় কখনও ঠিক হয় না।
কেট গ্রেগরি

1
যে কারণে আমি বলেছিলাম "এটি সন্ধান করা উপযুক্ত হবে"।
ক্রিসএফ

সি # সংকলকটি কীভাবে জানতে পারে যে সংগ্রহে. দৈর্ঘ্য () স্ট্যাক.পপ () যেভাবে সংগ্রহ করে সেটি সংশোধন করে না? আমি মনে করি সংকলকটি এটি অনুকূল করে নিলে আইএল পরীক্ষা করা ভাল হবে be সি ++ এ, আপনি কোনও পদ্ধতিটিকে কনস্ট হিসাবে চিহ্নিত করতে পারেন ('বস্তুটি পরিবর্তন করে না'), তাই সংকলক নিরাপদে এই অপ্টিমাইজেশনটি তৈরি করতে পারে।
জেবিআরওয়িলকিনসন

1
@ জেবিআরডাব্লু অপ্টিমাইজারগুলি যা এটি করে তারা সংগ্রহের পদ্ধতিগুলির ঠিক-এর-কল-ইট-কনস্টেন্স-এমনকি-এটি-সি -++ সম্পর্কে অবগত। সর্বোপরি আপনি কেবল সীমাবদ্ধ-চেক করতে পারেন যদি আপনি খেয়াল করতে পারেন যে কোনও কিছু সংগ্রহ এবং কীভাবে এর দৈর্ঘ্য পেতে হয় তাও জানেন।
কেট গ্রেগরি

9

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


1
প্রোগ্রামিং সম্পর্কে তাকে একটি বই দিন;)
জোয়ারি সেব্রিচটস

1
+1, কারণ আমাদের বেশিরভাগ বান্ধবী সম্ভবত কোডের স্পষ্টতার চেয়ে লেডি গাগায় আগ্রহী।
haploid

আপনি এটি ব্যাখ্যা করতে পারেন কেন এটি সুপারিশ করা হয়নি?
ম্যাকনিল

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

@ ম্যাকনিল আপনি যদি উচ্চ স্তরের ভাষায় কাজ করে থাকেন তবে একই স্তরে চিন্তা করুন।
টোকোথ

3

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

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

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

 bool isReady = (value > TriggerLevel);

এবং এটি সমাবেশ সমতুল্যে পরিণত হয়

isReady = 0
if (value > TriggerLevel)
{
  isReady = 1;
}

এটি হয় 3 টি চক্র গ্রহণ করবে, বা 10 যদি এটি লাফিয়ে যায় isReady=1;। তবে প্রসেসরের একটি একক-চক্র maxনির্দেশনা রয়েছে, সুতরাং এই ক্রমটি তৈরি করতে কোড লিখাই আরও ভাল যা সর্বদা 3 টি চক্র গ্রহণের গ্যারান্টিযুক্ত:

diff = value-TriggerLevel;
diff = max(diff, 0);
isReady = min(1,diff);

স্পষ্টতই, এখানে উদ্দেশ্যটি মূলটির চেয়ে কম পরিষ্কার। সুতরাং আমরা একটি ম্যাক্রো তৈরি করেছি, যা আমরা যখনই বুলিয়ান গ্রেটার-থান তুলনা চাই তখন ব্যবহার করি:

#define BOOL_GT(a,b) min(max((a)-(b),0),1)

//isReady = value > TriggerLevel;
isReady = BOOL_GT(value, TriggerLevel);

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


3

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

সি # তে উদাহরণস্বরূপ সংকলক কোডটি অপ্টিমাইজ করবে যদি আপনি কোনও অ্যারের দৈর্ঘ্য লুপ করেন তবে এটি জানেন যে অ্যারে অ্যাক্সেস করার সময় এটি সূচীটি পরীক্ষা করতে পারে না range আপনি যদি ভেরিয়েবলের মধ্যে অ্যারের দৈর্ঘ্যটি রেখে এটিকে আরও অনুকূল করার চেষ্টা করেন তবে আপনি লুপ এবং অ্যারের মধ্যে সংযোগটি ভেঙে ফেলবেন এবং কোডটি আসলে অনেক ধীর করে দেবেন।

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


3

আমার খুব সাধারণ কৌশল আছে।

  1. আমি আমার কোড কাজ করে।
  2. আমি এটি গতির জন্য পরীক্ষা করি।
  3. যদি এটি দ্রুত হয় তবে আমি অন্য কোনও বৈশিষ্ট্যের জন্য 1 ধাপে ফিরে যাই। যদি এটি ধীরে ধীরে হয় তবে আমি বাধাটি খুঁজতে এটির প্রোফাইল দিই।
  4. আমি বাধা ঠিক করলাম। পদক্ষেপ 1 এ ফিরে যান।

এই প্রক্রিয়াটি নষ্ট করার জন্য অনেক সময় সময় সাশ্রয় করে তবে সাধারণভাবে আপনি জানবেন যে এটি যদি হয়। যদি সন্দেহ থাকে তবে আমি এটি ডিফল্টরূপে আঁকড়ে থাকি।


2

শর্ট সার্কিটের সুবিধা নিন:

if(someVar || SomeMethod())

কোড নিতে ঠিক দীর্ঘ সময় নেয় এবং ঠিক তেমন পঠনযোগ্য:

if(someMethod() || someVar)

তবু এটি সময়ের সাথে সাথে আরও দ্রুত মূল্যায়ন করতে চলেছে।


1

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


6
এর ... আপনার গ্রাহকরা যে পারফরম্যান্স দেখছেন সে সম্পর্কে কী? আপনি কি তাদের জন্য নতুন কম্পিউটার কেনার জন্য যথেষ্ট ধনী?
রবার্ট হার্ভে

2
এবং আমরা প্রায় পারফরম্যান্স দেয়ালে আঘাত করেছি; মাল্টিকোর গণনা একমাত্র উপায়, তবে অপেক্ষা আপনার প্রোগ্রামগুলিকে এটি ব্যবহার করে না।
এমবিকিউ

+1 এই উত্তরটি প্রশ্নের সাথে আমার সম্পর্কিত মন্তব্যকে পরিপূরক করে।
তামারা উইজসম্যান

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

1
ভাল অভ্যাসে প্রবেশ করুন, তারপরে কোনও প্রোগ্রামার সময় নেয় না কারণ আপনি যা যা করেন তা সব সময় হয়।
ডোমিনিক ম্যাকডোনেল

1

সময়ের আগে খুব বেশি অপ্টিমাইটিস না করার চেষ্টা করুন, তারপরে আপনি যখন অপ্টিমাইজ করবেন তখন পঠনযোগ্যতা সম্পর্কে একটু চিন্তা করুন less

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

আপনি যদি কোডটি সবচেয়ে সুস্পষ্ট উপায়ে লেখেন তবে একটি জটিল মন্তব্য করুন যাতে জটিল পরিবর্তন করার সময় কেন এটি পরিবর্তন করা হয়েছে।

বিশেষত আপনার অর্থ হিসাবে, আমি দেখতে পেয়েছি যে অনেক সময় বুলিয়ান ডিফল্ট পদ্ধতির বিপরীতে করা কখনও কখনও সহায়তা করে:

for(int i = 0, j = collection.length(); i < j; i++ ){
// stuff here
}

হতে পারে

for(int i = collection.length(); i > 0; i-=1 ){
// stuff here
}

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

সি # তে উদাহরণস্বরূপ:

        string[] collection = {"a","b"};

        string result = "";

        for (int i = 0, j = collection.Count() - 1; i < j; i++)
        {
            result += collection[i] + "~";
        }

এই হিসাবে লেখা যেতে পারে:

        for (int i = collection.Count() - 1; i > 0; i -= 1)
        {
            result = collection[i] + "~" + result;
        }

(এবং হ্যাঁ, আপনার যোগদান করা বা স্ট্রিংবিল্ডারের সাথে হওয়া উচিত, তবে আমি একটি সাধারণ উদাহরণ দেওয়ার চেষ্টা করছি)

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

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


এটি একটি সমাধান, তবে
সংকলকটি

তবে সূচকটি উল্টিয়ে দিয়ে পুনরাবৃত্তিটি আরও জটিল হয়ে উঠতে পারে।
তামারা উইজসম্যান

@ স্টিজন যখন আমি এটি লিখছিলাম তখন আমি সি # এর কথা ভাবছিলাম, তবে সম্ভবত এই পরামর্শটি সেই কারণে ভাষা নির্দিষ্ট বিভাগেও আসে - সম্পাদনা দেখুন ... @ অবশ্যই, আমি মনে করি না এই প্রকৃতির কোনও পরামর্শ থাকলে অনেক আছে যে ঝুঁকি চালাতে না। আপনার // স্টাফ যদি একরকম স্ট্যাক ম্যানিপুলেশন হত তবে যুক্তিটি সঠিকভাবে বিপরীত করা সম্ভবও নাও হতে পারে, তবে বেশিরভাগ ক্ষেত্রে আইএমএইচও-র ক্ষেত্রে সাবধানতার সাথে করা হলে এটি এমন এবং খুব বিভ্রান্তিকর নয়।
বিল

তুমি ঠিক বলছো; সি ++ এ আমি এখনও 'স্বাভাবিক' লুপটি পছন্দ করি তবে পুনরাবৃত্তির ("আকার_ত i = 0; i <লেন; ++) এর জন্য পুনরাবৃত্তির () আকারের সাথে কল করা দৈর্ঘ্য () কল সহ i) {}) দুটি কারণে: আমি 'সাধারণ' ফরোয়ার্ড কাউন্টিং লুপটিকে আরও বেশি পঠনযোগ্য / বোধগম্য বলে মনে করি (তবে এটি সম্ভবত এটি আরও সাধারণ কারণ), এবং এটি লুপের বাইরে থাকা লুপের দৈর্ঘ্য () কলটি গ্রহণ করে।
stijn

1
  1. প্রোফাইলের। আমাদের কি সমস্যা আছে? কোথায়?
  2. 90% ক্ষেত্রে এটি কোনওভাবে আইও সম্পর্কিত, ক্যাশিং প্রয়োগ করুন (এবং আরও স্মৃতি পেতে পারেন)
  3. এটি সিপিইউ সম্পর্কিত হলে ক্যাচিং প্রয়োগ করুন
  4. যদি পারফরম্যান্স এখনও সমস্যা হয় তবে আমরা সহজ কৌশলগুলি ছেড়ে চলেছি - গণিতটি করুন do

1

আপনি যে সেরা সরঞ্জামগুলি খুঁজে পেতে পারেন সেগুলি ব্যবহার করুন - ভাল সংকলক, ভাল প্রোফাইলার, ভাল লাইব্রেরি। সঠিকভাবে আলগোরিদিম পান, বা আরও ভাল - এটি আপনার জন্য সঠিক লাইব্রেরিটি ব্যবহার করুন। তুচ্ছ লুপ অপটিমাইজেশন হ'ল ছোট আলু, প্লাস আপনি অপটিমাইজিং সংকলক হিসাবে স্মার্ট নন।


1

আমার পক্ষে সহজতম যখন স্ট্যাকটি ব্যবহার করা হয় তখনই সম্ভব হয় যখনই সাধারণ ক্ষেত্রে ব্যবহারের প্যাটার্নটি বিভিন্ন পরিসরে ফিট করে, বলুন, [০, )৪) তবে খুব কম ক্ষেত্রেই এর ছোট ছোট উপরের সীমা নেই।

সাধারণ সি উদাহরণ (আগে):

void some_hotspot_called_in_big_loops(int n, ...)
{
    // 'n' is, 99% of the time, <= 64.
    int* values = calloc(n, sizeof(int));

    // do stuff with values
    ...
    free(values);
}

এবং তারপর:

void some_hotspot_called_in_big_loops(int n, ...)
{
    // 'n' is, 99% of the time, <= 64.
    int values_mem[64] = {0}
    int* values = (n <= 64) ? values_mem: calloc(n, sizeof(int));

    // do stuff with values
    ...
    if (values != values_mem)
        free(values);
}

এই জাতীয় হটস্পটগুলি প্রোফাইলের ক্ষেত্রে প্রচুর পরিমাণে ফসল কাটিয়ে আমি এটিকে সাধারণকরণ করেছি:

void some_hotspot_called_in_big_loops(int n, ...)
{
    // 'n' is, 99% of the time, <= 64.
    MemFast values_mem;
    int* values = mf_calloc(&values_mem, n, sizeof(int));

    // do stuff with values
    ...

    mf_free(&values_mem);
}

উপরেরগুলি স্ট্যাকটি ব্যবহার করে যখন বরাদ্দ করা ডেটা সেই 99.9% ক্ষেত্রে যথেষ্ট ছোট হয় এবং অন্যথায় হিপ ব্যবহার করে।

সি ++ এ আমি এটি একটি আদর্শ-অনুবর্তী ছোট অনুক্রমের সাথে ( SmallVectorসেখানে বাস্তবায়নের অনুরূপ ) যা একই ধারণার আশেপাশে ঘুরে বেড়ায় এটি সাধারণীকরণ করেছি ।

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


0

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

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


0

এটি যদি সি ++ হয় তবে আপনার ++iবদলে অভ্যাস করা উচিত i++++iকখনই খারাপ হবে না, এর অর্থ দাঁড়ায় একা একা থাকা বিবৃতি এবং হ'ল কিছু ক্ষেত্রে এটি একটি পারফরম্যান্স উন্নতি হতে পারে।

অফ-সুযোগে বিদ্যমান কোডটি পরিবর্তন করা উপযুক্ত নয় যে এটি সাহায্য করবে, তবে এটি প্রবেশ করা ভাল অভ্যাস।


0

আমি এটি একটু ভিন্ন গ্রহণ করা আছে। কেবলমাত্র এখানে আপনি যে পরামর্শগুলি পেয়েছেন সেগুলি অনুসরণ করলে খুব বেশি পার্থক্য হবে না, কারণ আপনার কিছু ভুলত্রুটি করতে হবে, যা আপনাকে তখনই ঠিক করতে হবে, যা আপনার তখন শিখতে হবে।

আপনার যে ভুলটি করা দরকার তা হ'ল প্রত্যেকের মতো করে আপনার ডেটা স্ট্রাকচার ডিজাইন করা। এটি হ'ল রিলান্ড্যান্ট ডেটা এবং বিমূর্ততার অনেক স্তর সহ বৈশিষ্ট্য এবং বিজ্ঞপ্তিগুলি যা এটি পুরোপুরি সুসংগত রাখার চেষ্টা করে প্রচার করে।

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

কোডে কোনও বড় পরিবর্তন না করে আপনি এই সমস্যাগুলি কিছুটা সমাধান করতে সক্ষম হতে পারেন।

তারপরে আপনি যদি ভাগ্যবান হন তবে আপনি জানতে পারবেন যে কম ডেটা কাঠামো আরও ভাল, এবং বার্তাগুলির তরঙ্গগুলির সাথে একমত হয়ে অনেকগুলি বিষয় দৃ tight়ভাবে রাখার চেষ্টা করার চেয়ে অস্থায়ী অসঙ্গতি সহ্য করা ভাল is

আপনি কীভাবে লুপগুলি লিখেন তার সাথে আসলে কিছুই করার নেই।

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