首页 新闻 赞助 找找看

大家看看这块代码怎么优化一下?

0
悬赏园豆:50 [待解决问题]
int main() {
	std::vector<std::list<double>> _vector;
	for (int i = 0; i < 100000000; i++)
	{
		std::list<double> _list;
		_list.push_back(1.0);
		_list.push_back(2.0);
		_list.push_back(3.0);
		_list.push_back(4.0);
		_list.push_back(5.0);
		std::cout << "插入第" << i << "个值" << std::endl;
		_vector.push_back(_list);
	}
}
禅元天道的主页 禅元天道 | 初学一级 | 园豆:152
提问于:2021-09-03 10:43
< >
分享
所有回答(6)
0

用 java 重写。

领南森林公园 | 园豆:216 (菜鸟二级) | 2021-09-03 22:13

?????

支持(0) 反对(0) 禅元天道 | 园豆:152 (初学一级) | 2021-09-04 10:18

@禅元天道: java 是世界上最好的语言,用 java 重写,你不亏啊。[手动狗头]

支持(0) 反对(0) 领南森林公园 | 园豆:216 (菜鸟二级) | 2021-09-08 09:35
0

int main() {
std::vector<std::list<double>> _vector;
for (int i = 0; i < 100000000; i++)
{
std::list<double> _list;
for(double j=1.0;j<=5.0;j++){
_list.push_back(1.0);
}
std::cout << "插入第" << i << "个值" << std::endl;
_vector.push_back(_list);
}
}

除了五个push_back可以写成循环感觉没什么可优化的了

计算机知识杂谈 | 园豆:470 (菜鸟二级) | 2021-09-04 10:44

5个push_back只是一个示例,没抓住重点

支持(0) 反对(0) 禅元天道 | 园豆:152 (初学一级) | 2021-09-06 14:09
0
int main() {
	std::vector<std::list<double>> _vector;
	for (int i = 0; i < 100000000; i++)
	{
		std::list<double> _list;
		_list.push_back(i%5+1,0);
		std::cout << "插入第" << i << "个值" << std::endl;
		_vector.push_back(_list);
	}
}

这样可行?

if  __name__ =="__main__":
    for i in range(1,10000000):
        print(i%5+1)

结果:

>>> 1
>>> 2
>>> 3
>>> 4
>>> 5
>>> 1
>>> 2
>>> 3
>>> 4
>>> 5
>>> 1
>>> 2
>>> 3
>>> 4
>>> 5
>>> 1 
永远跟党走i | 园豆:1517 (小虾三级) | 2021-09-06 14:02

很明显你被楼上误导了,没抓住重点

支持(0) 反对(0) 禅元天道 | 园豆:152 (初学一级) | 2021-09-06 14:10

@禅元天道: 哥,你这里就是数据追加吧,

我要看看 后面的大佬咋优化

这个跟 net 类似吧

初始化 一个 list,然后填充十万次

list<user> userlist=new list<user>(){};
for(int i =0,i++, i<10000000){
    user  u=new (){
           id =i
       }
 userlist.appent(u)
}

这样的问题我也想问咋优化 呜呜呜

支持(0) 反对(0) 永远跟党走i | 园豆:1517 (小虾三级) | 2021-09-06 15:16
0

std::vector<std::list<double>> _vector;
_vector.reserve(100000000);
for (int i = 0; i < 100000000; ++i) {
_vector.emplace_back(std::list<double>{1.0, 2.0, 3.0, 4.0, 5.0});
}
C++11的话可以写成这样

FayeValentine | 园豆:208 (菜鸟二级) | 2021-09-08 16:27

还可以再优化 你的list 每次循环都构造析构,可以在循环外面创建好,这样只是每次循环copy构造一次。

支持(1) 反对(0) MyCPlusPlus | 园豆:43 (初学一级) | 2021-09-10 14:49
0
  1. 循环内的链表申明放到循环外来做,然后在循环内申明链表的地方改为list. clear()调用来达到目的。
    原因:每次循环开始都会重新构造list,循环结束会自动调用list析构函数释放内存。其实这里只需要每次循环前清空list即可,没必要每次重新构造list。当循环次数足够大时,效率上会有很大影响。(重新构造的开销要比list.clear()大,去调试跟踪下就知道了构造要重新生成head节点)list析构也是调用的clear。
  2. 如果list中的内容是固定的知道次数可以将list换成固定数组,构造一个局部变量即可,连清空的动作都可以省了(每次确保数组全部赋值的情况下)。
    c++引入类后比c更加“智能”,但同时也屏蔽了很多细节,就比如编译器给你调用的构造析构函数等。
Cloo_clam | 园豆:202 (菜鸟二级) | 2021-09-11 17:59
0

如果只考虑尾部插入元素的话, std::vector 或许不是一个好的选择,我们如果选择 std::list 的话,性能将是质的改变。同时也应该考虑减少内存的开辟和销毁操作。代码如下:

std::list<double> _cache;  // Reduce memory operations.
std::list<std::list<double>> _list;

clock_t start_time = clock(); // Timer to quantify performance.

while(_list.size() < 10000000)
{
    _cache.clear();
    while(_cache.size() < 5)
    {
        // Example behavior, this statement will cause partial performance waste.
        _cache.push_back(_cache.size() + 1.0); 
    }
    // It is not recommended to output debugging information here, which will cause huge performance pressure
    // std::cout << "插入第" << _list.size() + 1 << "个值" << std::endl;
    _list.push_back(_cache);
}
std::cout << "t-list time: " << clock() - start_time << std::endl;
怪小子 | 园豆:208 (菜鸟二级) | 2023-01-06 11:06

我尝试将测试量减少到 1000000 ,测试得到的结果相差很大,std::list 明显优异于 std::vector,其实不难理解,std::list 是开辟一份新的数据节点介入到尾部,而 std::vector 在内部开辟的空间不足时,会从开辟一份新的,更大的空间来存放数据,并且会将以前的数据拷贝到新的内存空间,然后将旧的空间析构,这无疑是一份巨大的负担。

以下测试结果是在测试量为 1000000,且在 Debug 模式下的结果。

作者原始代码消耗时间: 18121
我提交的代码消耗时间: 7693

以下测试结果是在测试量为 1000000,且在 Release 模式下的结果。

作者原始代码消耗时间: 1420
我提交的代码消耗时间: 571

支持(0) 反对(0) 怪小子 | 园豆:208 (菜鸟二级) | 2023-01-06 11:17
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册