C++ 如何在现有的c++;代码

C++ 如何在现有的c++;代码,c++,visual-studio-2015,C++,Visual Studio 2015,我需要在现有的c++代码中实现遥测功能,以分析哪些方法需要花费太多的时间来执行。可以在文本文件中记录时间戳。这是正确的方法还是有其他方法在c++中继续。由于我是vc++新手,请提供您的建议。我为C++代码自评测开发了最简单的代码。它以调用树的形式收集和显示统计信息。您可以根据需要对其进行修改。 要使用,只需在分析的块中添加跟踪宏即可 #pragma once #include <vector> #include <string> #include <windows

我需要在现有的c++代码中实现遥测功能,以分析哪些方法需要花费太多的时间来执行。可以在文本文件中记录时间戳。这是正确的方法还是有其他方法在c++中继续。由于我是vc++新手,请提供您的建议。

我为C++代码自评测开发了最简单的代码。它以调用树的形式收集和显示统计信息。您可以根据需要对其进行修改。 要使用,只需在分析的块中添加
跟踪
宏即可

#pragma once

#include <vector>
#include <string>
#include <windows.h>

typedef double Time;
typedef unsigned int uint;

#ifndef FLATTEN_RECURSION
#define FLATTEN_RECURSION 1
#endif

class Profiler
{
   static Time getCurrentTime()
   {
      LARGE_INTEGER time;
      LARGE_INTEGER freq;
      QueryPerformanceCounter(&time);
      QueryPerformanceFrequency(&freq);
      return 1.0 * time.QuadPart / freq.QuadPart;
   }

   struct Entry
   {
      Time fullTime_ = Time(0);
      const char* name_;
      uint started_ = 0;
      Time startTime_ = Time(0);

      Entry(const char* name) { name_ = name; }

      void start()
      {
         if (!started_) startTime_ = getCurrentTime();
         started_++;
      }

      void stop()
      {
         started_--;
         if (!started_)
            fullTime_ += getCurrentTime() - startTime_;
      }
   };

   struct CallTreeNode
   {
      const Entry& entry_;
      std::vector<CallTreeNode> childs_;

      CallTreeNode(const Entry& entry) : entry_(entry)
      {}

      CallTreeNode& addCall(const Entry& entry)
      {
         for (auto& itr : childs_)
            if (&itr.entry_ == &entry)
               return itr;
         childs_.push_back(CallTreeNode(entry));
         return childs_.back();
      }
   };

   std::vector<CallTreeNode*> callStack_;

   Entry rootEntry = Entry("root");
   CallTreeNode root = CallTreeNode(rootEntry);
   Time duration_;

   Profiler()
   {
      rootEntry.start();
      callStack_.push_back(&root);
   }

   void printTreeImpl(
      CallTreeNode& node,
      std::string& out,
      bool last = true,
      const std::string& prefix = "")
   {
      out += prefix + (last ? '\xC0' : '\xC3') + std::string("\xC4\xC4")
         + node.entry_.name_ + "  rate: " 
         + std::to_string(node.entry_.fullTime_ / duration_ * 100)
         + "% full time: " + std::to_string(node.entry_.fullTime_) + '\n';

      const int childsNum = (int)node.childs_.size();
      for (int i = 0; i < childsNum; i++)
         printTreeImpl(node.childs_[i], out, i == (childsNum - 1), prefix + (last ? ' ' : '\xB3') + "   ");
   }

   void forward(const Entry& entry)
   {
      callStack_.push_back(&callStack_.back()->addCall(entry));
   }

   void backward(const Entry& entry)
   {
      callStack_.pop_back();
   }

public:
   Profiler(Profiler const&) = delete;
   void operator=(Profiler const&) = delete;

   static Profiler& getInstance()
   {
      static Profiler instance;
      return instance;
   }

   static Entry newEntry(const char* name)
   {
      return Entry(name);
   }

   std::string printCallTree()
   {
      auto& inst = getInstance();
      inst.duration_ = inst.getCurrentTime() - inst.rootEntry.startTime_;
      inst.rootEntry.fullTime_ += duration_;
      std::string out;
      inst.printTreeImpl(root, out);
      return out;
   }


   class ProfilerAutoStopper
   {
      Entry& entry_;
   public:
      ProfilerAutoStopper(Entry& entry) : entry_(entry)
      {
         if (!entry_.started_ || !FLATTEN_RECURSION)
            getInstance().forward(entry_);
         entry_.start();
      }
      ~ProfilerAutoStopper()
      {
         entry_.stop();
         if (!entry_.started_ || !FLATTEN_RECURSION)
            getInstance().backward(entry_);
      }
   };
};

#define TRACE \
   static auto pflrEntry = Profiler::newEntry(__FUNCTION__); \
   Profiler::ProfilerAutoStopper autoStopper(pflrEntry);
出去 使用展平递归1

└──root  rate: 100.000000% full time: 0.190720
    └──main  rate: 99.944164% full time: 0.190614
        ├──foo  rate: 62.658680% full time: 0.119503
        ├──recursive  rate: 31.347459% full time: 0.059786
        └──bar  rate: 11.477065% full time: 0.021889
            └──foo  rate: 62.658680% full time: 0.119503

我通常使用外部分析器,而不是将其构建到代码中。Visual Studio(如果vc++中的v就是这个意思的话)有一套相当不错的评测工具。客户建议不要使用任何第三方工具。我建议将此添加到问题中。这是一个相当重要的细节。
└──root  rate: 100.000000% full time: 0.191205
    └──main  rate: 99.971599% full time: 0.191150
        ├──foo  rate: 62.788339% full time: 0.120054
        ├──recursive  rate: 31.276141% full time: 0.059801
        │   └──recursive  rate: 31.276141% full time: 0.059801
        │       └──recursive  rate: 31.276141% full time: 0.059801
        │           └──recursive  rate: 31.276141% full time: 0.059801
        │               └──recursive  rate: 31.276141% full time: 0.059801
        │                   └──recursive  rate: 31.276141% full time: 0.059801
        │                       └──recursive  rate: 31.276141% full time: 0.059801
        │                           └──recursive  rate: 31.276141% full time: 0.059801
        │                               └──recursive  rate: 31.276141% full time: 0.059801
        │                                   └──recursive  rate: 31.276141% full time: 0.059801
        └──bar  rate: 11.446139% full time: 0.021886
            └──foo  rate: 62.788339% full time: 0.120054
└──root  rate: 100.000000% full time: 0.190720
    └──main  rate: 99.944164% full time: 0.190614
        ├──foo  rate: 62.658680% full time: 0.119503
        ├──recursive  rate: 31.347459% full time: 0.059786
        └──bar  rate: 11.477065% full time: 0.021889
            └──foo  rate: 62.658680% full time: 0.119503