কলব্যাক সহ জাভাস্ক্রিপ্ট কোড কার্যকর করার সময়টি কীভাবে পরিমাপ করব?


319

আমার কাছে জাভাস্ক্রিপ্ট কোডের একটি অংশ রয়েছে যা আমি node.jsদোভাষী ব্যবহার করে চালাচ্ছি।

for(var i = 1; i < LIMIT; i++) {
  var user = {
    id: i,
    name: "MongoUser [" + i + "]"
  };
  db.users.save(user, function(err, saved) {
    if(err || !saved) {
      console.log("Error");
    } else {
      console.log("Saved");
    }
  });
}

এই ডাটাবেস সন্নিবেশ অপারেশনগুলির দ্বারা গ্রহণ করা সময় আমি কীভাবে পরিমাপ করতে পারি? আমি এই কোডের টুকরোটির আগে এবং তার আগে তারিখের মানগুলির পার্থক্যটি গণনা করতে পারি তবে কোডের অ্যাসিনক্রোনাস প্রকৃতির কারণে এটি ভুল হবে।


7
ডিবি কল করার আগে কেবল শুরুর সময় এবং শেষ সময় কলব্যাকের ভিতরে পড়ুন ..
বিফিল

একটি সম্ভাবনা রয়েছে যে ডিবি সন্নিবেশটি শেষ করে এবং কলব্যাক কার্যকর করার সময়টি একই নয় এবং এটি পরিমাপে একটি ত্রুটি পরিচয় করিয়ে দেবে?
স্টর্মশ্যাডো

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

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

আমি লিখেছি timerlogযা অনুরূপ console.time()তবে অতিরিক্ত বৈশিষ্ট্য সহ; github.com/brillout/timerlog
13 ই

উত্তর:


718

নোড.জেএস console.time()এবং ব্যবহার করুন console.timeEnd():

var i;
console.time("dbsave");

for(i = 1; i < LIMIT; i++){
    db.users.save({id : i, name : "MongoUser [" + i + "]"}, end);
}

end = function(err, saved) {
    console.log(( err || !saved )?"Error":"Saved");
    if(--i === 1){console.timeEnd("dbsave");}
};

31
নোডের জন্য পরিষ্কার এবং অন্তর্নির্মিত সমাধান।
বেহেল উয়ার

45
> এই ডিবি সন্নিবেশকরণ ক্রিয়াকলাপগুলির দ্বারা গৃহীত সময় কীভাবে পরিমাপ করা যায় তা আমি জানতে চাই। --- কনসোল.টাইমএন্ড ("dbsave") সময় কনসোল করার জন্য কেবল আউটপুট দেয়। আপনি এটি আর ব্যবহার করতে পারবেন না এবং কম নমনীয়। আপনার যদি আসল সময় মান প্রয়োজন হয়, যেমন আসল প্রশ্নের মতো, আপনি কনসোল.টাইম ব্যবহার করতে পারবেন না ("dbsave")
গোগাম্যান

@ গোগামান এটি একটি ভাল বিষয়, যেহেতু আপনি কনসোল.টাইমেন্ড () থেকে আউটপুট ক্যাপচার করতে পারবেন না। সম্ভবত এটি কোনও ফাইলের আউটপুটটি পাইপ করা এবং সেখান থেকে ব্যবহার করতে কার্যকর হতে পারে?
ডগ মোলিনাক্স

5
তাহলে নীচের উত্তরে কনসোল.টাইম () এবং প্রসেসহ্রটাইম () এর মধ্যে পার্থক্য কী?
হলুদ-সাধু

3
একটি নোট যুক্ত করা উচিত যে এক্সিকিউটিভ সময়টি তখন মুদ্রিত হয়, ঠিক এখন নতুন ব্যবহারকারীরা।
জাঙ্কো-এম

208

একটি পদ্ধতি আছে যা এর জন্য ডিজাইন করা হয়েছে। প্রক্রিয়াটি দেখুন

সুতরাং, আমি মূলত এটি আমার অ্যাপের শীর্ষে রেখেছি।

var start = process.hrtime();

var elapsed_time = function(note){
    var precision = 3; // 3 decimal places
    var elapsed = process.hrtime(start)[1] / 1000000; // divide by a million to get nano to milli
    console.log(process.hrtime(start)[0] + " s, " + elapsed.toFixed(precision) + " ms - " + note); // print message + time
    start = process.hrtime(); // reset the timer
}

তারপরে আমি এটি ব্যবহার করতে কতক্ষণ সময় লাগে তা দেখুন। এখানে একটি প্রাথমিক উদাহরণ যা "আউটপুট.টেক্সট" নামে একটি পাঠ্য ফাইলের বিষয়বস্তু মুদ্রণ করে:

var debug = true;
http.createServer(function(request, response) {

    if(debug) console.log("----------------------------------");
    if(debug) elapsed_time("recieved request");

    var send_html = function(err, contents) {
        if(debug) elapsed_time("start send_html()");
        response.writeHead(200, {'Content-Type': 'text/html' } );
        response.end(contents);
        if(debug) elapsed_time("end send_html()");
    }

    if(debug) elapsed_time("start readFile()");
    fs.readFile('output.txt', send_html);
    if(debug) elapsed_time("end readFile()");

}).listen(8080);

আপনি একটি টার্মিনাল (বেস শেল) চালাতে পারেন একটি দ্রুত পরীক্ষা এখানে:

for i in {1..100}; do echo $i; curl http://localhost:8080/; done

3
এটি কোনও উপায়ে কনসোল.টাইম সলিউশনের চেয়ে উন্নত?
স্ক্র্যাভি

31
হ্যাঁ, এটি অনেক বেশি সুনির্দিষ্ট এবং আপনি ফলটি পরিবর্তনশীল হিসাবে সংরক্ষণ করতে পারেন
ডালাস ক্লার্ক

এটি আমার জন্য কাজ করে, যেহেতু আমি বেশ কয়েকবার
টাইমারকে

2
process.hrtime(start)দু'বার ফোন দিলে কেন ? এর কোন বিশেষ কারণ আছে কি?
সোহেল সি

1
প্রক্রিয়া.hrtime ([সময়]), যেখানে সময় হ'ল একটি alচ্ছিক প্যারামিটার যা বর্তমান সময়ের সাথে পৃথক হওয়ার জন্য পূর্ববর্তী প্রক্রিয়া। রাইমটাইম () কলের ফলাফল হতে হবে। এটি বর্তমান কল এবং পূর্ববর্তী এইচআরটাইম কলের মধ্যে পার্থক্য দেয়।
নিলেশ জৈন

72

ইনভোকিং console.time('label')বর্তমান সময়কে মিলি সেকেন্ডে রেকর্ড করবে, তারপরে কল console.timeEnd('label')করা সেই বিন্দু থেকে সময়কালটি প্রদর্শন করবে।

মিলিসেকেন্ডে সময় স্বয়ংক্রিয়ভাবে লেবেলের পাশাপাশি মুদ্রিত হবে, সুতরাং আপনাকে কোনও লেবেল মুদ্রণ করতে কনসোল.লগের জন্য আলাদা কল করতে হবে না:

console.time('test');
//some code
console.timeEnd('test'); //Prints something like that-> test: 11374.004ms

আরও তথ্যের জন্য, মজিলার বিকাশকারী ডক্সটি দেখুনconsole.time



1
গৃহীত উত্তরটি আমার কোডটি ব্যবহারের উত্তর দেওয়ার পরে সংশোধিত হয়েছিল
jfcorugedo

23

অবাক করা কেউ এখনও লাইব্রেরিতে নতুন নির্মিত সম্পর্কে উল্লেখ করেনি:

নোড> = 8.5 এ উপলব্ধ এবং আধুনিক ব্রাউজারে হওয়া উচিত

https://developer.mozilla.org/en-US/docs/Web/API/Performance

https://nodejs.org/docs/latest-v8.x/api/perf_hooks.html#

নোড 8.5 ~ 9.x (ফায়ারফক্স, ক্রোম)

// const { performance } = require('perf_hooks'); // enable for node
const delay = time => new Promise(res=>setTimeout(res,time))
async function doSomeLongRunningProcess(){
  await delay(1000);
}
performance.mark('A');
(async ()=>{
  await doSomeLongRunningProcess();
  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
  const measure = performance.getEntriesByName('A to B')[0];
  // firefox appears to only show second precision.
  console.log(measure.duration);
  performance.clearMeasures(); // apparently you should remove entries...
  // Prints the number of milliseconds between Mark 'A' and Mark 'B'
})();

https://repl.it/@CodyGeisler/NodeJsPerformanceHooks

নোড 10.x

https://nodejs.org/docs/latest-v10.x/api/perf_hooks.html

const { PerformanceObserver, performance } = require('perf_hooks');
const delay = time => new Promise(res => setTimeout(res, time))
async function doSomeLongRunningProcess() {
    await delay(1000);
}
const obs = new PerformanceObserver((items) => {
    console.log('PerformanceObserver A to B',items.getEntries()[0].duration);
    performance.clearMarks();
});
obs.observe({ entryTypes: ['measure'] });

performance.mark('A');

(async function main(){
    try{
        await performance.timerify(doSomeLongRunningProcess)();
        performance.mark('B');
        performance.measure('A to B', 'A', 'B');
    }catch(e){
        console.log('main() error',e);
    }
})();

আমাকে TypeError: performance.getEntriesByName is not a functionনোড ভি 10.4.1 এ দেয়
জেরেমি থিল

আমি উদাহরণটি তৈরি করেছি যাতে আপনি এটি অনলাইনে চালাতে পারেন। এটি নোড 9.7.1। যদি এটি v10.4.1 এ কাজ না করে তবে আমি ভাবছি কী পরিবর্তন হতে পারে!
কোডি G

1
Stability: 1 - Experimentalহতে পারে? :) nodejs.org/docs/latest-v8.x/api/…
জেরেমি থিল

হ্যাঁ নিশ্চিতভাবেই এটি পরিবর্তিত হয়েছে। ভি 10- তে একটি নতুন পর্যবেক্ষক রয়েছে, আপনি নোডেজ.এস / ডকস / স্লেস্ট- ভি 10.x/api/docamentation.html এ ডকস দেখতে পাবেন । আমি সুযোগ পেলেই আপডেট করব!
কোডি G

19

যে কারও জন্য কনসোল আউটপুটের পরিবর্তে সময় অতিবাহিত মান পেতে চায়:

@ D.Deriso পরামর্শ হিসাবে প্রক্রিয়া। রাইটটাইম () ব্যবহার করুন , নীচে আমার সহজ পদ্ধতির নীচে:

function functionToBeMeasured() {
    var startTime = process.hrtime();
    // do some task...
    // ......
    var elapsedSeconds = parseHrtimeToSeconds(process.hrtime(startTime));
    console.log('It takes ' + elapsedSeconds + 'seconds');
}

function parseHrtimeToSeconds(hrtime) {
    var seconds = (hrtime[0] + (hrtime[1] / 1e9)).toFixed(3);
    return seconds;
}

16
var start = +new Date();
var counter = 0;
for(var i = 1; i < LIMIT; i++){
    ++counter;
    db.users.save({id : i, name : "MongoUser [" + i + "]"}, function(err, saved) {
          if( err || !saved ) console.log("Error");
          else console.log("Saved");
          if (--counter === 0) 
          {
              var end = +new Date();
              console.log("all users saved in " + (end-start) + " milliseconds");
          }
    });
}

5
এর অর্থ কী তা বোঝার জন্য আমাকে সিনট্যাক্স '+ নতুন তারিখ ()' সন্ধান করতে হয়েছিল। এই উত্তরের মন্তব্যে ( স্ট্যাকওভারফ্লো.com/ a/ 221565 / 5114 ), পারফরম্যান্সের কারণে এবং পাঠযোগ্যতার জন্য সেই ফর্মটি ব্যবহার করা ভাল ধারণা নয়। আমি কিছুটা আরও ভার্বোজের কিছু পছন্দ করি যাতে এটি পাঠকের কাছে পরিষ্কার হয়। : এছাড়াও এই উত্তর দেখার stackoverflow.com/a/5036460/5114
Mnebuerquo

3
আমি প্রায়শই var start = process.hrtime(); ... var end = process.hrtime(start);উচ্চ রেজোলিউশন সময় পেতে ব্যবহার করি (যদি আমার সাব মিলিসেকেন্ড যথার্থতা আশা করা দরকার)
আন্দ্রে সিডোরভ

9

পুরানো প্রশ্ন তবে একটি সাধারণ এপিআই এবং হালকা ওজন সমাধানের জন্য; আপনি পারফিউ ব্যবহার করতে পারেন যা process.hrtimeঅভ্যন্তরীণভাবে উচ্চ-রেজোলিউশন রিয়েল টাইম ( ) ব্যবহার করে।

var perfy = require('perfy');

function end(label) {
    return function (err, saved) {
        console.log(err ? 'Error' : 'Saved'); 
        console.log( perfy.end(label).time ); // <——— result: seconds.milliseconds
    };
}

for (var i = 1; i < LIMIT; i++) {
    var label = 'db-save-' + i;
    perfy.start(label); // <——— start and mark time
    db.users.save({ id: i, name: 'MongoUser [' + i + ']' }, end(label));
}

মনে রাখবেন যে প্রতিটি সময় perfy.end(label)বলা হয়, সেই উদাহরণটি স্বয়ংক্রিয়ভাবে ধ্বংস হয়ে যায়।

প্রকাশ: ডিডিরিসোর উত্তর থেকে অনুপ্রাণিত এই মডিউলটি লিখেছেন । ডক্স এখানে


2

আপনি চেষ্টা করতে পারেন বেঞ্চমার্ক.জেএস কে । এটি তাদের মধ্যে node.js এর মধ্যে অনেক প্ল্যাটফর্ম সমর্থন করে।


11
আপনি যদি এই ব্যবহারের ক্ষেত্রে বেঞ্চমার্ক.জেএস কীভাবে ব্যবহার করতে চান তার একটি উদাহরণ যুক্ত করতে পারলে ভাল হবে।
পেটাঃ

2

আপনি নির্বাহকও চেষ্টা করতে পারেন । এটি আপনাকে মতামত দেয়:

var t = require("exectimer");

var myFunction() {
   var tick = new t.tick("myFunction");
   tick.start();
   // do some processing and end this tick
   tick.stop();
}

// Display the results
console.log(t.timers.myFunction.duration()); // total duration of all ticks
console.log(t.timers.myFunction.min()); // minimal tick duration
console.log(t.timers.myFunction.max()); // maximal tick duration
console.log(t.timers.myFunction.mean()); // mean tick duration
console.log(t.timers.myFunction.median()); // median tick duration

এক্সিকিউটর ব্যবহার করার এখন আরও একটি সহজ উপায় আছে কারণ এখন এটি কোডটি পরিমাপ করার জন্য মোড়ানো করতে পারে। আপনার কোডটি এভাবে মোড়ানো হতে পারে:

var t = require('exectimer'),
Tick = t.Tick;

for(var i = 1; i < LIMIT; i++){
    Tick.wrap(function saveUsers(done) {
        db.users.save({id : i, name : "MongoUser [" + i + "]"}, function(err, saved) {
            if( err || !saved ) console.log("Error");
            else console.log("Saved");
            done();
        });
    });
}

// Display the results
console.log(t.timers.myFunction.duration()); // total duration of all ticks
console.log(t.timers.saveUsers.min()); // minimal tick duration
console.log(t.timers.saveUsers.max()); // maximal tick duration
console.log(t.timers.saveUsers.mean()); // mean tick duration
console.log(t.timers.saveUsers.median()); // median tick duration

1

এডাব্লুএস থেকে আজুরে যাওয়ার সময় আমার একই সমস্যা ছিল

এক্সপ্রেস এবং দের জন্য, আপনি ইতিমধ্যে ব্যবহার করতে পারেন, বিদ্যমান সময় () এবং সময় সমাপ্তি ()

অ্যাজুরের জন্য, এটি ব্যবহার করুন: https://github.com/manoharreddyporeddy/my-nodejs-notes/blob/master/performance_timers_helper_nodejs_azure_aws.js

এই সময় () এবং সময়সীমা () বিদ্যমান এইচআরটাইম () ফাংশনটি ব্যবহার করে যা উচ্চ-রেজোলিউশনকে আসল সময় দেয়।

আশাকরি এটা সাহায্য করবে.


0

এবং অন্য বিকল্পটি হল এক্সপ্রেস-ডিবাগ সরঞ্জামটি ব্যবহার করা :

এক্সপ্রেস-ডিবাগ এক্সপ্রেসের জন্য একটি বিকাশকারী সরঞ্জাম। এটি সাধারণ মিডলওয়্যার যা আপনার এইচটিএমএলে একটি অ-বাধাজনক উপায়ে কার্যকর ডিবাগিং আউটপুটকে ইনজেকশন দেয়।

এটি সুবিধাজনকভাবে একটি প্রোফাইল প্যানেল সরবরাহ করে:

মোট রেক প্রসেসিং সময়। মিডলওয়্যার, পরম এবং রুটের সময়

এছাড়াও। উপরের উত্তরগুলি যুক্ত করতে আপনি কেবলমাত্র বিকাশের পরিবেশের জন্য কোনও প্রোফাইল কোড সক্ষম করতে এই উত্তরটি পরীক্ষা করতে পারেন ।

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