当前位置:  开发笔记 > 编程语言 > 正文

快速而肮脏的方式来分析您的代码

如何解决《快速而肮脏的方式来分析您的代码》经验,为你挑选了1个好方法。

当您想获得有关特定代码路径的性能数据时,您使用什么方法?



1> Motti..:

这种方法有一些局限性,但我仍然觉得它非常有用.我会在前面列出限制(我知道)并让任何想要使用它的人自行承担风险.

    我发布的原始版本报告了在递归调用中花费的时间(正如答案的评论中所指出的).

    它不是线程安全的,在我添加代码以忽略递归之前它不是线程安全的,现在它的线程安全性更低.

    虽然它被称为很多次(数百万)非常有效,但它会对结果产生可测量的影响,因此您测量的范围将比您不需要的时间长.


当手头的问题无法对我的所有代码进行分析或者从我想验证的分析器中获取一些数据时,我使用这个类.基本上,它总结了您在特定块中花费的时间,并在程序结束时将其输出到调试流(可通过DbgView查看),包括执行代码的次数(以及当然花费的平均时间)).

#pragma once
#include 
#include 
#include 
#include 

namespace scope_timer {
    class time_collector : boost::noncopyable {
        __int64 total;
        LARGE_INTEGER start;
        size_t times;
        const TCHAR* name;

        double cpu_frequency()
        { // cache the CPU frequency, which doesn't change.
            static double ret = 0; // store as double so devision later on is floating point and not truncating
            if (ret == 0) {
                LARGE_INTEGER freq;
                QueryPerformanceFrequency(&freq);
                ret = static_cast(freq.QuadPart);
            }
            return ret;
        }
        bool in_use;

    public:
        time_collector(const TCHAR* n)
            : times(0)
            , name(n)
            , total(0)
            , start(LARGE_INTEGER())
            , in_use(false)
        {
        }

        ~time_collector()
        {
            std::basic_ostringstream msg;
            msg << _T("scope_timer> ") <<  name << _T(" called: ");

            double seconds = total / cpu_frequency();
            double average = seconds / times;

            msg << times << _T(" times total time: ") << seconds << _T(" seconds  ")
                << _T(" (avg ") << average <<_T(")\n");
            OutputDebugString(msg.str().c_str());
        }

        void add_time(__int64 ticks)
        {
            total += ticks;
            ++times;
            in_use = false;
        }

        bool aquire()
        {
            if (in_use)
                return false;
            in_use = true;
            return true;
        }
    };

    class one_time : boost::noncopyable {
        LARGE_INTEGER start;
        time_collector* collector;
    public:
        one_time(time_collector& tc)
        {
            if (tc.aquire()) {
                collector = &tc;
                QueryPerformanceCounter(&start);
            }
            else
                collector = 0;
        }

        ~one_time()
        {
            if (collector) {
                LARGE_INTEGER end;
                QueryPerformanceCounter(&end);
                collector->add_time(end.QuadPart - start.QuadPart);
            }
        }
    };
}

// Usage TIME_THIS_SCOPE(XX); where XX is a C variable name (can begin with a number)
#define TIME_THIS_SCOPE(name) \
    static scope_timer::time_collector st_time_collector_##name(_T(#name)); \
    scope_timer::one_time st_one_time_##name(st_time_collector_##name)


@Motti:对于检测递归代码,您只需要测量最外层的调用.
推荐阅读
mobiledu2402851203
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有