• 算法复杂度与执行时间


    算法复杂度与执行时间

    实际测试

    通过测试(代码见下文,编译指令:g++ -std=c++11 -O0 t.cpp)当代计算机耗时如下表所示,测试机器:

    • Ubuntu 20
    • CPU,intel i7-8750H
    • Mem,16G & DDR4 & 2400MT/s

    测试结果

    执行次数 优化选项 耗时(ms)
    14000(数万) -O0 0.771(毫秒级)
    14000 -O2 0.613
    4000000(数百万) -O0 35.249(数十毫秒)
    4000000 -O2 29.859
    28000000(数千万) -O0 240.723(数百毫秒)
    28000000 -O2 197.916
    196000000(数亿) -O0 1686.2(秒级)
    196000000 -O2 1410.34
    8000000000(数十亿) -O0 68834(数十秒级)
    8000000000 -O2 56567.1

    总结

    不同机器执行耗时可能不同,比如嵌入式CPU对比服务器机器可能慢了几十倍,但实验结果所表现出的现象不变

    竞赛时可以按照数据规模选择算法,如果数据量不大暴力法是很好的选择,简单快速

    算法复杂度不能超过亿次级别,否则很容易超时,数十亿一定超时,千万级别比较保险,最好是百万级别及以下

    测试代码

    #include <cmath>
    #include <chrono>
    #include <iostream>
    
    double cnt_g = 0;
    
    void base_f() {
        cnt_g += 3.1415926 * (std::rand() % 7);
    }
    
    long long liner_f(long long cnt) {
       for(int i = 0; i < cnt; i++) base_f(); 
       return cnt;
    }
    
    long long logn_f(long long cnt) {
    
        int cnt_x = static_cast<long long>(std::log(cnt*1.0));
        return liner_f(cnt_x);    
    }
    
    long long nlogn_f(long long cnt) {
        long long exe_cnt = 0;
        for(int i = 0; i < cnt; i++) {
            exe_cnt += logn_f(cnt);
        }
        return exe_cnt;
    }
    
    long long pow2_f(long long cnt){
        long long exe_cnt = 0;
        for(int i = 0; i < cnt; i++){
            exe_cnt += liner_f(cnt);
        }
        return exe_cnt;
    }
    
    long long pow2logn_f(long long cnt){
        long long exe_cnt = 0;
        auto cnt_x = static_cast<long long>(std::log(cnt*1.0));
        for(int i = 0; i < cnt_x; i++){
            exe_cnt += pow2_f(cnt);
        }
        return exe_cnt;
    }
    
    long long pow2lognlogn_f(long long cnt){
        long long exe_cnt = 0;
        auto cnt_x = static_cast<long long>(std::log(cnt*1.0));
        for(int i = 0; i < cnt_x; i++){
            exe_cnt += pow2logn_f(cnt);
        }
        return exe_cnt;
    }
    
    long long cube_f(long long cnt) {
        long long exe_cnt = 0;
        for(int i = 0; i < cnt; i++){
            exe_cnt += pow2_f(cnt);
        }
        return exe_cnt;
    }
    
    
    std::pair<long long, long long > time_stat(long long (*f)(long long ), long long cnt) {
    
        auto res = std::pair<long long, long long>();
        auto start_tp = std::chrono::steady_clock::now();
    
        res.first = f(cnt);
    
        auto end_tp = std::chrono::steady_clock::now();
        auto span = std::chrono::duration_cast<std::chrono::microseconds>(end_tp - start_tp).count();
    
        res.second = span;
    
        return res;
    }
    
    void helper(const std::string& msg, long long (*f)(long long), long long cnt) {
    
        auto res = time_stat(f, cnt);
        std::cout << msg << ",  cnt: " << cnt << ", exe_cnt: " << res.first 
                  << ", time: " << res.second/1000.0 << "ms, cnt_g: " << cnt_g << std::endl;
    }
    
    int main(int argc, char** argv) {
    
        if(argc != 2) {
            std::cerr << "ERR, please do: ./exe_able cnt" << std::endl;
            return -1;
        }
        else {
            long long cnt = std::stoll(argv[1]);
    
            helper("logn", logn_f, cnt);
            helper("n", liner_f, cnt);
            helper("nlogn", nlogn_f, cnt);
            helper("pow2", pow2_f, cnt);
            helper("pow2logn", pow2logn_f, cnt);
            helper("pow2lognlogn", pow2lognlogn_f, cnt);
            helper("cube", cube_f, cnt);
        }
    }
    

    输出示例

    编译命令:g++ -std=c++11 -O2 test.cpp

    执行命令:./a.out 2000

    控制台输出:

    logn,  cnt: 2000, exe_cnt: 7, time: 0.034ms, cnt_g: 59.6903
    n,  cnt: 2000, exe_cnt: 2000, time: 0.074ms, cnt_g: 18959.5
    nlogn,  cnt: 2000, exe_cnt: 14000, time: 0.588ms, cnt_g: 151833
    pow2,  cnt: 2000, exe_cnt: 4000000, time: 29.557ms, cnt_g: 3.78582e+07
    pow2logn,  cnt: 2000, exe_cnt: 28000000, time: 201.471ms, cnt_g: 3.01775e+08
    pow2lognlogn,  cnt: 2000, exe_cnt: 196000000, time: 1409.63ms, cnt_g: 2.14893e+09
    cube,  cnt: 2000, exe_cnt: 8000000000, time: 57545.9ms, cnt_g: 7.7547e+10
    
  • 相关阅读:
    在多个游戏视图间切换环境准备
    精灵动画Animation对话框组成Idle动画的各精灵
    空函数有参函数调用参数的注意事项Swift 1.1语言
    使用NGUINGUI的相关介绍
    ARP侦查工具Netdiscover
    使用recon/domains-hosts/baidu_site模块,枚举baidu网站的子域
    Transform组件C#游戏开发快速入门
    为什么使用BeagleBoneBeagleBone的优点
    Java-JNA调用DLL(转)
    关于IP网段间互访的问题—路由是根本(转)
  • 原文地址:https://www.cnblogs.com/jiahu-Blog/p/14314388.html
Copyright © 2020-2023  润新知