网站建设资讯

NEWS

网站建设资讯

set、vector与list的构造与排序的耗时测试

测试目标

创新互联为企业级客户提高一站式互联网+设计服务,主要包括成都网站建设、网站设计重庆APP软件开发、微信小程序开发、宣传片制作、LOGO设计等,帮助客户快速提升营销能力和企业形象,创新互联各部门都有经验丰富的经验,可以确保每一个作品的质量和创作周期,同时每年都有很多新员工加入,为我们带来大量新的创意。 

测试在成员个数不断递增的情况下,set、vector与list的构造与排序的耗时变化,找出set耗时连续超过其他容器耗时的成员个数


测试方式

  • set使用直接插入

  • vector使用assign构造并使用全局sort排序

  • list使用assign构造与成员sort的排序之间

  • 比较的是耗时时间大小,对耗时的具体值不关心,因为不同的机器配置不一样

测试结论

由于设定的连续超过次数不同,得到的成员个数值也不同,并且随着连续超过上限的增加而增加,因此现在得到的成员个数值并不准确,如:

在连续超过上限为10时,成员个数最大在700左右

在连续超过上限为20时,成员个数最大在2000左右

但有一点可以肯定:set的边插入边排序效率,没有vector与list的赋值或排序高,如果有海量数据排序的情况,用vector或list的赋值后排序的性能相对于set比较好。


测试代码

// 主逻辑 main.cpp
#include "TimeConsume.h"
#include "Random.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

// set耗时是否连续超出其他容器
bool is_continue_beyond(uint64_t vector_time, uint64_t list_time, uint64_t set_time, uint64_t beyond_num) {
    static uint64_t s_beyond_num = beyond_num; 
    if (set_time > list_time && set_time > vector_time) {
	--s_beyond_num;
    } else {
	s_beyond_num = beyond_num;
    }

    return s_beyond_num == 0;
}

int main(int argc, char** argv) {

    uint64_t member_count_num = 0;
    uint64_t member_add_num = 0;
    uint64_t beyond_num = 0;
    if (argc != 4) {
	cout << "input: " << argv[0] << " member_start_num member_add_num beyond_num" << endl;
	return -1;
    } else {
	member_count_num = strtoull(argv[1], NULL, 10);
	member_add_num = strtoull(argv[2], NULL, 10);
	beyond_num = strtoull(argv[3], NULL, 10);
    }

    uint64_t vector_time = 0;
    uint64_t list_time   = 0;
    uint64_t set_time    = 0;

    while (!is_continue_beyond(vector_time, list_time, set_time, beyond_num)) {
	vector input_random_num; // 使用一样的随机数据
	Random random;
	random.SetRandomNum >(member_count_num, input_random_num);

	// 构造排序函数
	vector monitor_vector; // 外部定义容器,防止构造析构带来的时间计算
	auto vector_sort = [&]() {
	    monitor_vector.assign(input_random_num.begin(), input_random_num.end());
	    sort(monitor_vector.begin(), monitor_vector.end());
	};

	list monitor_list;
	auto list_sort = [&]() {
	    monitor_list.assign(input_random_num.begin(), input_random_num.end());
	    monitor_list.sort();
	};

	set monitor_set;
	auto set_sort = [&](){
	    monitor_set.insert(input_random_num.begin(), input_random_num.end());
	};

	// 统计排序时间
        TimeConsume vector_time_consume(vector_sort);
        TimeConsume list_time_consume(list_sort);
        TimeConsume set_time_consume(set_sort);

	vector_time = vector_time_consume.GetFnTime();
	list_time = list_time_consume.GetFnTime();
	set_time = set_time_consume.GetFnTime();

	cout << "count:" << member_count_num<< "\t" << "vector_time:" << vector_time << "\t" << "list_time:" << list_time << "\t" << "set_time:" << set_time << endl;
	sleep(0.5);
	member_count_num += member_add_num;
    }
    return 0;
}
/*
TimeConsume.h
用于获得程序运行的时间消耗,支持函数对象(C++11新标准)
获得的耗时为微秒级
*/
#ifndef TIME_CONSUME_H
#define TIME_CONSUME_H

#include 
#include 
#include 
using std::function;

#define SEC_RATIO_MSEC 1000
#define SEC_RATIO_USEC (1000*SEC_RATIO_MSEC)

class TimeConsume {
public:
    TimeConsume(const function &monitor_fn = [](){;})
	: m_monitor_fn(monitor_fn) {
	    Clear();
    }

    ~TimeConsume()
    {;}

    // 设置耗时监控的函数对象
    inline function SetMonitorFn(const function &monitor_fn()) {
    	auto old_monitor_fn = m_monitor_fn;
    	m_monitor_fn = monitor_fn;
    	return old_monitor_fn;
    }

    // 记录开始监控的时间点
    inline void Start() {
	    gettimeofday(&m_start, NULL);
    }
    
    // 记录结束监控的时间点
    inline void End() {
	    gettimeofday(&m_end, NULL);
    }

    // 依据开始和结束监控的时间点,得到微秒级耗时
    inline uint64_t GetIntervalTime() {
    	if ((m_end.tv_sec > m_start.tv_sec)
    	    || (m_end.tv_sec == m_start.tv_sec && m_end.tv_usec >= m_start.tv_usec)) {
    	    return (m_end.tv_sec - m_start.tv_sec)*SEC_RATIO_USEC + (m_end.tv_usec - m_start.tv_usec); 
    	} else {
    	    return 0;
    	}
    }

    // 获得监控函数对象的微秒级运行耗时
    inline uint64_t GetFnTime() {
        Clear();
    	Start();
    	m_monitor_fn();
    	End();
    	return GetIntervalTime();
    }

protected:
    // 格式化内部相关值
    inline void Clear() {
    	m_start.tv_sec = 0;
    	m_start.tv_usec = 0;
    	m_end.tv_sec = 0;
    	m_end.tv_usec = 0;
    }

private:
    struct timeval m_start;
    struct timeval m_end;
    function m_monitor_fn;
};
#endif
/*
Random.h
可以向STL 容器里填充指定个数的随机值,取值范围在[0-RAND_MAX],RAND_MAX为最大值的整数常量表达式。此值依赖实现。保证此值至少为32767
*/
#ifndef RANDOM_H
#define RANDOM_H

#include 
#include 
using std::inserter;

class Random {
public:
    Random() {
	srand(time(NULL));
    }

    ~Random()
    {;}

    template 
    inline void SetRandomNum(uint64_t count, ContainerT &container) {
	auto iter = inserter(container, container.end());
	for (uint64_t i = 0; i < count; ++i) {
	    iter = rand();
	}
    }
};

如果对测试有什么疑问或建议,欢迎大家来讨论


文章名称:set、vector与list的构造与排序的耗时测试
当前地址:http://cdweb.net/article/giggje.html