সি ++ তে কোনও ফাংশনের কার্যকরকরণের সময় পরিমাপ করা


138

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

process_user_cpu_clock, captures user-CPU time spent by the current process

এখন, আমি পরিষ্কার করছি না যে আমি উপরের ফাংশনটি ব্যবহার করি, আমি কি সিপিইউ on ফাংশনে ব্যয় করা একমাত্র সময় পাব?

দ্বিতীয়ত, আমি উপরের ফাংশনটি ব্যবহার করার কোনও উদাহরণ খুঁজে পাইনি। উপরের ফাংশনটি কীভাবে ব্যবহার করতে পারেন দয়া করে কেউ আমাকে সহায়তা করতে পারেন?

পিএস: এখনই, আমি std::chrono::system_clock::now()সেকেন্ডে সময় পেতে ব্যবহার করছি তবে প্রতিবার বিভিন্ন সিপিইউ লোডের কারণে এটি আমাকে বিভিন্ন ফলাফল দেয়।


2
লিনাক্স ব্যবহারের জন্য: clock_gettime.. গিগি অন্যান্য ঘড়ির সংজ্ঞা দেয়: typedef system_clock steady_clock; typedef system_clock high_resolution_clock;উইন্ডোজে, ব্যবহার করুন QueryPerformanceCounter
ব্র্যান্ডন

এই প্রশ্নের সদৃশ নয় এই এক বা পরিস্থিতিতে সমাধান বিভিন্ন করতে পারি?
উত্তর

আমার একটি ক্রিয়াকলাপের দুটি বাস্তবায়ন রয়েছে এবং কোনটি আরও ভাল সম্পাদন করে তা সন্ধান করতে চাই।
উত্তর

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

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

উত্তর:


264

এটি সি ++ 11-এ খুব সহজেই ব্যবহারযোগ্য পদ্ধতি। আপনাকে হেডার std::chrono::high_resolution_clockথেকে ব্যবহার করতে হবে <chrono>

এটি এর মতো ব্যবহার করুন:

#include <iostream>
#include <chrono>

void function()
{
    long long number = 0;

    for( long long i = 0; i != 2000000; ++i )
    {
       number += 5;
    }
}

int main()
{
    auto t1 = std::chrono::high_resolution_clock::now();
    function();
    auto t2 = std::chrono::high_resolution_clock::now();

    auto duration = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();

    std::cout << duration;
    return 0;
}

এটি ফাংশনের সময়কাল পরিমাপ করবে।

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


আমি যখন এই ফাংশনটি ব্যবহার করি, প্রথমবারে এটি আমাকে 118440535 মাইক্রোসেকেন্ডস দেয় এবং একই ফাংশনের দ্বিতীয় রানে এটি আমাকে 83221031 মাইক্রোসেকেন্ড দেয়। আমি যখন কেবলমাত্র সেই ফাংশনের সময়কাল পরিমাপ করি তখন দুটি সময়ের পরিমাপের সমান হওয়া উচিত নয়?
Xara

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

1
হ্যাঁ, আপনার যদি সময়ের গড় প্রয়োজন হয় তবে এটি এটির পক্ষে একটি ভাল উপায়। তিন রান করুন, এবং গড় গণনা করুন।
ভিক্টর

3
আপনি কি দয়া করে সাধারণভাবে "নেমস্পেস ব্যবহার না করে" কোড পোস্ট করতে পারেন? কোথা থেকে আসে তা দেখতে এটি সহজ করে তোলে।
স্নোম্যান

1
এটি একটি হওয়া উচিত নয় steady_clock? এটি কি high_resolution_clockনন-একঘেয়ে ঘড়ি হতে পারে?
গিলেস্পি

15

এখানে একটি ফাংশন যা আর্গুমেন্ট হিসাবে পাস হওয়া কোনও ফাংশনের সম্পাদনের সময় পরিমাপ করবে:

#include <chrono>
#include <utility>

typedef std::chrono::high_resolution_clock::time_point TimeVar;

#define duration(a) std::chrono::duration_cast<std::chrono::nanoseconds>(a).count()
#define timeNow() std::chrono::high_resolution_clock::now()

template<typename F, typename... Args>
double funcTime(F func, Args&&... args){
    TimeVar t1=timeNow();
    func(std::forward<Args>(args)...);
    return duration(timeNow()-t1);
}

ব্যবহারের উদাহরণ:

#include <iostream>
#include <algorithm>

typedef std::string String;

//first test function doing something
int countCharInString(String s, char delim){
    int count=0;
    String::size_type pos = s.find_first_of(delim);
    while ((pos = s.find_first_of(delim, pos)) != String::npos){
        count++;pos++;
    }
    return count;
}

//second test function doing the same thing in different way
int countWithAlgorithm(String s, char delim){
    return std::count(s.begin(),s.end(),delim);
}


int main(){
    std::cout<<"norm: "<<funcTime(countCharInString,"precision=10",'=')<<"\n";
    std::cout<<"algo: "<<funcTime(countWithAlgorithm,"precision=10",'=');
    return 0;
}

আউটপুট:

norm: 15555
algo: 2976

2
@ রেস্টলেস সি 0 বিআর: এটি বাস্তবায়িত সংজ্ঞায়িত, (ওয়াল ক্লক) এর high_resolution_clockএকটি উপাস বা তৃতীয় স্বতন্ত্র ঘড়ি হতে পারে। বিস্তারিত এখানে দেখুন । সিপু ঘড়ির জন্য, ব্যবহার করা যেতে পারেsystem_clocksteady_clockstd::clock
জাহিদ

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

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

1
সমস্যাটি হ'ল তারা অনস্কেপড W যেটি নিয়ে আমি চিন্তিত তা হ'ল এই জাতীয় ম্যাক্রোগুলি আমার কোডের অন্তর্ভুক্ত (সম্ভবত অপ্রত্যক্ষভাবে একটি লাইব্রেরির অংশ হিসাবে) পাওয়া একটি শিরোলেখ ফাইলের মধ্যে রয়েছে। আপনি যদি চান তবে কি হয় তার স্বাদ পেতে চান সাধারণ নামগুলি ম্যাক্রোগুলির জন্য ব্যবহৃত হয়, windows.hএকটি তুচ্ছ সি ++ প্রকল্পের অন্তর্ভুক্ত। সংক্রান্ত assertসর্বপ্রথমে: "যে যদিও iovi অ যদিও bovi";)। দ্বিতীয়ত, স্ট্যান্ডার্ড লাইব্রেরিতে সমস্ত সিদ্ধান্ত (কখনও কখনও দশকের দশক আগের ডেটিং) আসলে আধুনিক মানের দ্বারা একটি ভাল ধারণা হিসাবে বিবেচিত হয় না। এর একটি কারণ রয়েছে, কেন সি ++ মডিউল ডিজাইনার ডিফল্টরূপে ম্যাক্রোগুলি রফতানি না করার জন্য খুব চেষ্টা করে।
মাইক এমবি

2
@ জাহিদ: ধন্যবাদ সেক্ষেত্রে আমার মন্তব্যগুলি বাতিল এবং শূন্য বিবেচনা করুন।
মাইক এমবি

9

কার্যকর প্রোগ্রামটি গ্রহণের সময় কার্যকরভাবে সন্ধান করতে find

#include <iostream>
#include <ctime> // time_t
#include <cstdio>

void function()
{
     for(long int i=0;i<1000000000;i++)
     {
        // do nothing
     }
}

int main()
{

time_t begin,end; // time_t is a datatype to store time values.

time (&begin); // note time before execution
function();
time (&end); // note time after execution

double difference = difftime (end,begin);
printf ("time taken for function() %.2lf seconds.\n", difference );

return 0;
}

6
এটি অত্যন্ত
ত্রুটিযুক্ত

7

স্কট মায়ার্স বইতে আমি সর্বজনীন জেনেরিক ল্যাম্বডা অভিব্যক্তির একটি উদাহরণ পেয়েছি যা ফাংশন সম্পাদনের সময় পরিমাপ করার জন্য ব্যবহার করা যেতে পারে। (সি ++ 14)

auto timeFuncInvocation = 
    [](auto&& func, auto&&... params) {
        // get time before function invocation
        const auto& start = std::chrono::high_resolution_clock::now();
        // function invocation using perfect forwarding
        std::forward<decltype(func)>(func)(std::forward<decltype(params)>(params)...);
        // get time after function invocation
        const auto& stop = std::chrono::high_resolution_clock::now();
        return stop - start;
     };

সমস্যাটি হ'ল আপনি কেবলমাত্র একটি নির্বাহকে পরিমাপ করছেন যাতে ফলাফলগুলি খুব আলাদা হতে পারে। একটি নির্ভরযোগ্য ফলাফল পেতে আপনার কার্যকর পরিমাণের একটি বিশাল পরিমাণ পরিমাপ করা উচিত। কোড :: ডাইভ 2015 সম্মেলনে আন্ড্রেই আলেকজান্দ্রেস্কু বক্তৃতা অনুসারে - ফাস্ট কোড আই লিখন:

পরিমাপ করা সময়: tm = t + tq + tn + to

কোথায়:

tm - পরিমাপ (পর্যবেক্ষণ) সময়

t - আগ্রহের আসল সময়

tq - সময় সংযোজন আওয়াজ দ্বারা যোগ করা

tn - সময় শব্দের বিভিন্ন উত্স দ্বারা যুক্ত

থেকে - ওভারহেড সময় (পরিমাপ, লুপিং, কলিং ফাংশন)

বক্তৃতার পরে তিনি যা বলেছিলেন সে অনুসারে আপনার ফলাফল হিসাবে আপনার এই বিশাল সংখ্যক কার্যকর হওয়া উচিত। আমি আপনাকে উত্সাহিত করি যে বক্তৃতায় তিনি কেন ব্যাখ্যা করেছেন তা দেখার জন্য।

এছাড়াও গুগল থেকে একটি খুব ভাল গ্রন্থাগার রয়েছে - https://github.com/google/benchmark । এই গ্রন্থাগারটি ব্যবহার করা খুব সহজ এবং শক্তিশালী। আপনি ইউটিউবে চ্যানডলার ক্যারথের কয়েকটি বক্তৃতা চেকআউট করতে পারেন যেখানে তিনি অনুশীলনে এই গ্রন্থাগারটি ব্যবহার করছেন। উদাহরণস্বরূপ CppCon 2017: চ্যানডলার ক্যারুথ "আরও কোথাও চলছে";

ব্যবহারের উদাহরণ:

#include <iostream>
#include <chrono>
#include <vector>
auto timeFuncInvocation = 
    [](auto&& func, auto&&... params) {
        // get time before function invocation
        const auto& start = high_resolution_clock::now();
        // function invocation using perfect forwarding
        for(auto i = 0; i < 100000/*largeNumber*/; ++i) {
            std::forward<decltype(func)>(func)(std::forward<decltype(params)>(params)...);
        }
        // get time after function invocation
        const auto& stop = high_resolution_clock::now();
        return (stop - start)/100000/*largeNumber*/;
     };

void f(std::vector<int>& vec) {
    vec.push_back(1);
}

void f2(std::vector<int>& vec) {
    vec.emplace_back(1);
}
int main()
{
    std::vector<int> vec;
    std::vector<int> vec2;
    std::cout << timeFuncInvocation(f, vec).count() << std::endl;
    std::cout << timeFuncInvocation(f2, vec2).count() << std::endl;
    std::vector<int> vec3;
    vec3.reserve(100000);
    std::vector<int> vec4;
    vec4.reserve(100000);
    std::cout << timeFuncInvocation(f, vec3).count() << std::endl;
    std::cout << timeFuncInvocation(f2, vec4).count() << std::endl;
    return 0;
}

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


আকর্ষণীয় - এখানে কোনও ফাংশন টেম্পলেট ব্যবহার করে ল্যাম্বডা ব্যবহার করে কী লাভ?
ব্যবহারকারী 48956

1
মূল পার্থক্যটি হ'ল এটি একটি কলযোগ্য বস্তু তবে প্রকৃতপক্ষে আপনি ভ্যারিয়েডিক টেম্পলেট এবং স্ট্যান্ড :: ফলাফল_of_t এর সাথে খুব অনুরূপ কিছু পেতে পারেন।
ক্রিজিসটফ সোমারফিল্ড

@ ক্রিজিসটফসফারসফার্ড কীভাবে এটি ফাংশন পদ্ধতিগুলির জন্য করবেন, যখন আমি সময়টি পাস করি (অবজেক্ট.মথোড 1) এটি ত্রুটি "অ-মানক সিনট্যাক্স;" সদস্যকে পয়েন্টার তৈরি করতে 'এবং' ব্যবহার করে "
রবিনএটটেক

টাইমফুনস ইনভোকেশন ([& অবজেক্টনেম] (অটো এবং অ্যান্ড ... আরগস)) N অবজেক্টনেম.মোথডনাম (স্ট্যান্ড :: ফরোয়ার্ড <ডিক্লাইপ (আরগস)> (আরগস) ...);}, আরজি 1, আরগ 2, ...); অথবা অবজেক্টনেমের আগে সাইন ইন করুন (তারপরে আপনার কাছে সেই বস্তুর একটি অনুলিপি থাকবে)
ক্রিজিসটফ সোমারফিল্ড

4

পুরানো সি ++, বা সি এর জন্য সহজ উপায়:

#include <time.h> // includes clock_t and CLOCKS_PER_SEC

int main() {

    clock_t start, end;

    start = clock();
    // ...code to measure...
    end = clock();

    double duration_sec = double(end-start)/CLOCKS_PER_SEC;
    return 0;
}

সময়ের সুনির্দিষ্ট সময় হয় 1.0/CLOCKS_PER_SEC


1
এটি পোর্টেবল নয়। এটি লিনাক্সে প্রসেসরের সময় এবং উইন্ডোতে ঘড়ির সময় পরিমাপ করে।
বাগস্কোয়াশের

2
  • এটি সি ++ 11 এ ব্যবহার করা খুব সহজ পদ্ধতি।
  • আমরা শিরোনাম থেকে স্ট্যান্ডার্ড :: ক্রোনো :: হাই_রেসোলিউশন_ক্লক ব্যবহার করতে পারি
  • আমরা পদ্ধতি প্রয়োগের সময়টি খুব বেশি পাঠযোগ্য আকারে মুদ্রণের জন্য একটি পদ্ধতি লিখতে পারি।

উদাহরণস্বরূপ, 1 এবং 100 মিলিয়নের মধ্যে সমস্ত মৌলিক সংখ্যাগুলি খুঁজতে, এটি প্রায় 1 মিনিট এবং 40 সেকেন্ড সময় নেয়। সুতরাং মৃত্যুদন্ড কার্যকর করার সময়টি মুদ্রিত হবে:

Execution Time: 1 Minutes, 40 Seconds, 715 MicroSeconds, 715000 NanoSeconds

কোডটি এখানে:

#include <iostream>
#include <chrono>

using namespace std;
using namespace std::chrono;

typedef high_resolution_clock Clock;
typedef Clock::time_point ClockTime;

void findPrime(long n, string file);
void printExecutionTime(ClockTime start_time, ClockTime end_time);

int main()
{
    long n = long(1E+8);  // N = 100 million

    ClockTime start_time = Clock::now();

    // Write all the prime numbers from 1 to N to the file "prime.txt"
    findPrime(n, "C:\\prime.txt"); 

    ClockTime end_time = Clock::now();

    printExecutionTime(start_time, end_time);
}

void printExecutionTime(ClockTime start_time, ClockTime end_time)
{
    auto execution_time_ns = duration_cast<nanoseconds>(end_time - start_time).count();
    auto execution_time_ms = duration_cast<microseconds>(end_time - start_time).count();
    auto execution_time_sec = duration_cast<seconds>(end_time - start_time).count();
    auto execution_time_min = duration_cast<minutes>(end_time - start_time).count();
    auto execution_time_hour = duration_cast<hours>(end_time - start_time).count();

    cout << "\nExecution Time: ";
    if(execution_time_hour > 0)
    cout << "" << execution_time_hour << " Hours, ";
    if(execution_time_min > 0)
    cout << "" << execution_time_min % 60 << " Minutes, ";
    if(execution_time_sec > 0)
    cout << "" << execution_time_sec % 60 << " Seconds, ";
    if(execution_time_ms > 0)
    cout << "" << execution_time_ms % long(1E+3) << " MicroSeconds, ";
    if(execution_time_ns > 0)
    cout << "" << execution_time_ns % long(1E+6) << " NanoSeconds, ";
}

0

এখানে কোনও ফাংশন বা যে কোনও কোড ব্লকের সময় অতিবাহিত করার জন্য একমাত্র শিরোনামের একমাত্র শ্রেণীর টেম্পলেট:

#ifndef EXECUTION_TIMER_H
#define EXECUTION_TIMER_H

template<class Resolution = std::chrono::milliseconds>
class ExecutionTimer {
public:
    using Clock = std::conditional_t<std::chrono::high_resolution_clock::is_steady,
                                     std::chrono::high_resolution_clock,
                                     std::chrono::steady_clock>;
private:
    const Clock::time_point mStart = Clock::now();

public:
    ExecutionTimer() = default;
    ~ExecutionTimer() {
        const auto end = Clock::now();
        std::ostringstream strStream;
        strStream << "Destructor Elapsed: "
                  << std::chrono::duration_cast<Resolution>( end - mStart ).count()
                  << std::endl;
        std::cout << strStream.str() << std::endl;
    }    

    inline void stop() {
        const auto end = Clock::now();
        std::ostringstream strStream;
        strStream << "Stop Elapsed: "
                  << std::chrono::duration_cast<Resolution>(end - mStart).count()
                  << std::endl;
        std::cout << strStream.str() << std::endl;
    }

}; // ExecutionTimer

#endif // EXECUTION_TIMER_H

এখানে এর কিছু ব্যবহার রয়েছে:

int main() {
    { // empty scope to display ExecutionTimer's destructor's message
         // displayed in milliseconds
         ExecutionTimer<std::chrono::milliseconds> timer;

         // function or code block here

         timer.stop();

    } 

    { // same as above
        ExecutionTimer<std::chrono::microseconds> timer;

        // code block here...

        timer.stop();
    }

    {  // same as above
       ExecutionTimer<std::chrono::nanoseconds> timer;

       // code block here...

       timer.stop();

    }

    {  // same as above
       ExecutionTimer<std::chrono::seconds> timer;

       // code block here...

       timer.stop();

    }              

    return 0;
}

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


ব্যক্তিগতভাবে, stop()সদস্য ফাংশনটির প্রয়োজন হয় না কারণ ধ্বংসকারী আপনার জন্য টাইমার বন্ধ করে দেয়।
কেসি

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

@ ক্যাসি ... এটি একই ক্ষেত্রের মধ্যে একাধিক টাইমার অবজেক্টগুলিকেও থাকতে দেয়, এটির সত্যই এটির প্রয়োজন হয় না, তবে কেবল একটি কার্যকর বিকল্প option
ফ্রান্সিস কুগার

এই উদাহরণ উপস্থাপিত আকারে সংকলন করা যায় না। ত্রুটিটি "অপারেটরের সাথে কোনও মিল নেই << ..." সম্পর্কিত!
Celdor

@ ফিল্ডারটিতে আপনার উপযুক্ত কি অন্তর্ভুক্ত রয়েছে; যেমন <chrono>?
ফ্রান্সিস কুগলার

0

আমি ব্যবহার করার প্রস্তাব দিই steady_clockযা, একঘেয়ে হতে অসদৃশ guarunteed হয় high_resolution_clock

#include <iostream>
#include <chrono>

using namespace std;

unsigned int stopwatch()
{
    static auto start_time = chrono::steady_clock::now();

    auto end_time = chrono::steady_clock::now();
    auto delta    = chrono::duration_cast<chrono::microseconds>(end_time - start_time);

    start_time = end_time;

    return delta.count();
}

int main() {
  stopwatch(); //Start stopwatch
  std::cout << "Hello World!\n";
  cout << stopwatch() << endl; //Time to execute last line
  for (int i=0; i<1000000; i++)
      string s = "ASDFAD";
  cout << stopwatch() << endl; //Time to execute for loop
}

আউটপুট:

Hello World!
62
163514

0

আপনার কাছে একটি সাধারণ শ্রেণি থাকতে পারে যা এই ধরণের পরিমাপের জন্য ব্যবহার করা যেতে পারে।

class duration_printer {
public:
    duration_printer() : __start(std::chrono::high_resolution_clock::now()) {}
    ~duration_printer() {
        using namespace std::chrono;
        high_resolution_clock::time_point end = high_resolution_clock::now();
        duration<double> dur = duration_cast<duration<double>>(end - __start);
        std::cout << dur.count() << " seconds" << std::endl;
    }
private:
    std::chrono::high_resolution_clock::time_point __start;
};

কেবলমাত্র কাজটি প্রয়োজন সেই ফাংশনটির শুরুতে আপনার ফাংশনে কোনও অবজেক্ট তৈরি করা

void veryLongExecutingFunction() {
    duration_calculator dc;
    for(int i = 0; i < 100000; ++i) std::cout << "Hello world" << std::endl;
}

int main() {
    veryLongExecutingFunction();
    return 0;
}

এবং এটাই. আপনার প্রয়োজনীয়তা মাপসই ক্লাস পরিবর্তন করা যেতে পারে।


0

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

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

https://github.com/CarloWood/cwds/blob/master/benchmark.h#L40


0

আপনি যদি সময় এবং কোডের লাইনগুলি নিরাপদ করতে চান তবে আপনি ফাংশন এক্সিকিউশন সময়কে এক লাইনের ম্যাক্রো পরিমাপ করতে পারবেন:

ক) উপরে প্রস্তাবিত হিসাবে একটি সময় পরিমাপের শ্রেণি প্রয়োগ করুন (এখানে অ্যান্ড্রয়েডের জন্য আমার বাস্তবায়নটি রয়েছে):

class MeasureExecutionTime{
private:
    const std::chrono::steady_clock::time_point begin;
    const std::string caller;
public:
    MeasureExecutionTime(const std::string& caller):caller(caller),begin(std::chrono::steady_clock::now()){}
    ~MeasureExecutionTime(){
        const auto duration=std::chrono::steady_clock::now()-begin;
        LOGD("ExecutionTime")<<"For "<<caller<<" is "<<std::chrono::duration_cast<std::chrono::milliseconds>(duration).count()<<"ms";
    }
};

খ) বর্তমান ফাংশনটির নাম TAG হিসাবে ব্যবহার করে এমন একটি সুবিধাজনক ম্যাক্রো যুক্ত করুন (এখানে ম্যাক্রো ব্যবহার করা গুরুত্বপূর্ণ, অন্যথায় __FUNCTION__আপনি MeasureExecutionTimeযে ফাংশনটি পরিমাপ করতে চান তার পরিবর্তে মূল্যায়ন করবে)

#ifndef MEASURE_FUNCTION_EXECUTION_TIME
#define MEASURE_FUNCTION_EXECUTION_TIME const MeasureExecutionTime measureExecutionTime(__FUNCTION__);
#endif

গ) আপনি যে ফাংশনটি পরিমাপ করতে চান তার শুরুতে আপনার ম্যাক্রো লিখুন। উদাহরণ:

 void DecodeMJPEGtoANativeWindowBuffer(uvc_frame_t* frame_mjpeg,const ANativeWindow_Buffer& nativeWindowBuffer){
        MEASURE_FUNCTION_EXECUTION_TIME
        // Do some time-critical stuff 
}

যা নিম্নলিখিত ফলাফলের জন্য ফলাফল করবে:

ExecutionTime: For DecodeMJPEGtoANativeWindowBuffer is 54ms

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

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