测试目标
测试在成员个数不断递增的情况下,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 <unistd.h> #include <vector> #include <list> #include <set> #include <algorithm> #include <iostream> #include <cstdint> #include <string> 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<uint64_t > input_random_num; // 使用一样的随机数据 Random random; random.SetRandomNum<vector<uint64_t> >(member_count_num, input_random_num); // 构造排序函数 vector<uint64_t> monitor_vector; // 外部定义容器,防止构造析构带来的时间计算 auto vector_sort = [&]() { monitor_vector.assign(input_random_num.begin(), input_random_num.end()); sort(monitor_vector.begin(), monitor_vector.end()); }; list<uint64_t> monitor_list; auto list_sort = [&]() { monitor_list.assign(input_random_num.begin(), input_random_num.end()); monitor_list.sort(); }; set<uint64_t> 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 <sys/time.h> #include <ctime> #include <functional> using std::function; #define SEC_RATIO_MSEC 1000 #define SEC_RATIO_USEC (1000*SEC_RATIO_MSEC) class TimeConsume { public: TimeConsume(const function<void()> &monitor_fn = [](){;}) : m_monitor_fn(monitor_fn) { Clear(); } ~TimeConsume() {;} // 设置耗时监控的函数对象 inline function<void()> SetMonitorFn(const function<void()> &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<void()> m_monitor_fn; }; #endif
/* Random.h 可以向STL 容器里填充指定个数的随机值,取值范围在[0-RAND_MAX],RAND_MAX为最大值的整数常量表达式。此值依赖实现。保证此值至少为32767 */ #ifndef RANDOM_H #define RANDOM_H #include <ctime> #include <iterator> using std::inserter; class Random { public: Random() { srand(time(NULL)); } ~Random() {;} template <typename ContainerT> inline void SetRandomNum(uint64_t count, ContainerT &container) { auto iter = inserter(container, container.end()); for (uint64_t i = 0; i < count; ++i) { iter = rand(); } } };
如果对测试有什么疑问或建议,欢迎大家来讨论
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。