V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  scenix  ›  全部回复第 1 页 / 共 10 页
回复总数  181
1  2  3  4  5  6  7  8  9  10  
2017-10-28 17:03:20 +08:00
回复了 scenix 创建的主题 C C++的 set 爆内存,求助
@xziar 就是心里不平衡,老子费劲巴拉的写了一两天,还让各路神仙隔空 debug,结果跟 10 行 python 差不多。
2017-10-26 14:17:12 +08:00
回复了 scenix 创建的主题 C C++的 set 爆内存,求助
@xziar
@wevsty 感谢二位,我这边只是随手写的测试代码,想看下不同语言在面对类似情景下的性能表现,没打算复用,东西存进去就没打算放出来,也就没写 delete。
不过我修改了一下 python 的代码,性能也有不少提高,二位能否看下这段 python 在你们机器上的表现?
我本机如果用 pypy 去跑,性能和 c++几乎一样,真是意外。

big_dict = {}
with open("data/test_log.txt") as f_in:
for line in f_in:
items = line.strip().split(' ')
key = items[0]
if key not in big_dict:
big_dict[key] = set(items[1:])
else:
big_dict[key].update(items[1:]) // 原来的 for 循环去掉了,直接用 set 内建的 update 方法
print "total keys:", len(big_dict)
2017-10-26 14:13:47 +08:00
回复了 scenix 创建的主题 C C++的 set 爆内存,求助
2017-10-26 11:40:03 +08:00
回复了 scenix 创建的主题 C C++的 set 爆内存,求助
@wevsty 少帖了几个 include 补上

#include <iostream>
#include <fstream>
#include <string>
#include<unordered_map>
#include<unordered_set>
2017-10-26 11:39:19 +08:00
回复了 scenix 创建的主题 C C++的 set 爆内存,求助
@wevsty 感谢你的回复,我重新检查了一下 cmake,虽然我开了 O3 优化,但是不小心打开了 gdb 的选项,去掉后速度明显上来了。
我编译了你的代码和我的代码,速度上有些不一样。能否在你的机器上编译运行一下我优化过的代码?看看速度会不会快些。
我没有用 string_view,stringstream,只是优化了插入部分的写法。
盼复。



#include<unordered_set>

using namespace std;

// data/test_log.txt 文件是一个 600MB 的日志文件
const string IN_FNAME = "data/test_log.txt";
unordered_map<string, unordered_set<string>* > big_dict;

void process_file(const string fname, unordered_map<string,unordered_set<string> *> & big_dict) {
ifstream f_in;
f_in.open(fname, ios::in);
string line = "";
int total_line = 0;
size_t start =0, end = 0;
while(getline(f_in, line)) {
++total_line;
start =0, end = 0;// c++没有内建 string 的分割,自己 diy 个
end = line.find_first_of(' ',start);
const string key = line.substr(start, end - start);
// 寻找是否存在 key
auto iter = big_dict.find(key);
unordered_set<string> *p = NULL;
if(iter == big_dict.end()) {
p = new unordered_set<string>;
// 原来的写法是 big_dict[key]=p,需要查找一次,优化之
big_dict.insert(make_pair(key,p));
} else {
// 如果已经有结果了,直接暂存结果到指针 p 中
p = iter->second;
}

start = end+1;
while(start<line.size()) {
end = line.find_first_of(' ',start);
if(string::npos == end) end = line.size() - 1;
// 原来的写法是 big_dict[key]->insert,需要查找一次,优化之
p->insert(line.substr(start, end - start));
start = end + 1;
}
}
f_in.close();

}
int main() {

process_file(IN_FNAME, big_dict);

cout<<"Total Keys:"<<big_dict.size()<<endl;

return 0;
}
2017-10-25 14:36:57 +08:00
回复了 scenix 创建的主题 C C++的 set 爆内存,求助
@pezy centos7 用的 cmake 开了-O3 优化
2017-10-25 12:33:09 +08:00
回复了 scenix 创建的主题 C C++的 set 爆内存,求助
@wevsty 大概就是这样一个日志文件:

$ head data/test_log.txt
03:07:02 giantbee systemd: Removed slice user-0.slice. Sep 25 03:07:02 giantbee systemd: Removed slice user-0.slice.
03:07:02 giantbee systemd: Stopping user-0.slice. Sep 25 03:07:02 giantbee systemd: Stopping user-0.slice.
03:07:02 giantbee kibana: "type":"log" "@timestamp":"2017-09-24T19:07:02Z" "tags":["warning" "elasticsearch" "admin"] "pid":22721 "message":"Unable to revive connection: http://localhost:9200/" Sep 25 03:07:02 giantbee kibana: {"type":"log","@timestamp":"2017-09-24T19:07:02Z","tags":["warning","elasticsearch","admin"],"pid":22721,"message":"Unable to revive connection: http://localhost:9200/"}
03:07:02 giantbee kibana: "type":"log" "@timestamp":"2017-09-24T19:07:02Z" "tags":["warning" "elasticsearch" "admin"] "pid":22721 "message":"No living connections" Sep 25 03:07:02 giantbee kibana: {"type":"log","@timestamp":"2017-09-24T19:07:02Z","tags":["warning","elasticsearch","admin"],"pid":22721,"message":"No living connections"}
03:07:05 giantbee kibana: "type":"log" "@timestamp":"2017-09-24T19:07:05Z" "tags":["warning" "elasticsearch" "admin"] "pid":22721 "message":"Unable to revive connection: http://localhost:9200/" Sep 25 03:07:05 giantbee kibana: {"type":"log","@timestamp":"2017-09-24T19:07:05Z","tags":["warning","elasticsearch","admin"],"pid":22721,"message":"Unable to revive connection: http://localhost:9200/"}
03:07:05 giantbee kibana: "type":"log" "@timestamp":"2017-09-24T19:07:05Z" "tags":["warning" "elasticsearch" "admin"] "pid":22721 "message":"No living connections" Sep 25 03:07:05 giantbee kibana: {"type":"log","@timestamp":"2017-09-24T19:07:05Z","tags":["warning","elasticsearch","admin"],"pid":22721,"message":"No living connections"}
03:07:07 giantbee kibana: "type":"log" "@timestamp":"2017-09-24T19:07:07Z" "tags":["warning" "elasticsearch" "admin"] "pid":22721 "message":"Unable to revive connection: http://localhost:9200/" Sep 25 03:07:07 giantbee kibana: {"type":"log","@timestamp":"2017-09-24T19:07:07Z","tags":["warning","elasticsearch","admin"],"pid":22721,"message":"Unable to revive connection: http://localhost:9200/"}
03:07:07 giantbee kibana: "type":"log" "@timestamp":"2017-09-24T19:07:07Z" "tags":["warning" "elasticsearch" "admin"] "pid":22721 "message":"No living connections" Sep 25 03:07:07 giantbee kibana: {"type":"log","@timestamp":"2017-09-24T19:07:07Z","tags":["warning","elasticsearch","admin"],"pid":22721,"message":"No living connections"}
03:07:10 giantbee kibana: "type":"log" "@timestamp":"2017-09-24T19:07:10Z" "tags":["warning" "elasticsearch" "admin"] "pid":22721 "message":"Unable to revive connection: http://localhost:9200/" Sep 25 03:07:10 giantbee kibana: {"type":"log","@timestamp":"2017-09-24T19:07:10Z","tags":["warning","elasticsearch","admin"],"pid":22721,"message":"Unable to revive connection: http://localhost:9200/"}
03:07:10 giantbee kibana: "type":"log" "@timestamp":"2017-09-24T19:07:10Z" "tags":["warning" "elasticsearch" "admin"] "pid":22721 "message":"No living connections" Sep 25 03:07:10 giantbee kibana: {"type":"log","@timestamp":"2017-09-24T19:07:10Z","tags":["warning","elasticsearch","admin"],"pid":22721,"message":"No living connections"}


另外 @williamscorn 的代码中 sstream 的>>操作是不是不等价于 python 和 go 的 split,这次是空格,下次我要用\t 或者是|来分割字符串的时候是不是 sstream 就不好用了啊?
2017-10-25 12:16:42 +08:00
回复了 scenix 创建的主题 C C++的 set 爆内存,求助
@wevsty @williamscorn @hncqp 非常感谢提点。爆内存的问题的确是我错误的使用了 substr,修改为 line.substr(start,end - start)后,的确内存占用很少了,大概只有 200M。但是执行的速度还是比不上 python 和 go,不管是我原来的代码,还是 @williamscorn 提供的代码,大概都要慢一倍的样子。

P.S. @williamscorn 提供的代码中我每个循环加了一句 ss.clear(); 其余没有动。
2017-10-25 11:00:06 +08:00
回复了 scenix 创建的主题 C C++的 set 爆内存,求助
@arakashic 感谢回复,程序的思路是逐行读取日志文件,用空格切分,第一个字段作为 key,剩下的字段去重后作为 value。只是为了看下处理效率,当然接着写的话,可以把 big_dict 里面的东西每个(key,value)作为一行输出到一个文件里吧。
2017-10-25 10:53:12 +08:00
回复了 scenix 创建的主题 C C++的 set 爆内存,求助
@lcdtyph @acros 我运行的时候一直用 top 命令看内存,眼看着内存使用一路飙到 3G,然后被 kill,没有异常,没有 core,直接 kill 的。
我的 set 存的时候是这么写的:

auto *p = new unordered_set<string>;
big_dict[key] = p;

可以看到只 new 了没有 delete。但是我如果不在这个 new 的 set 里面存东西的话,也不会爆内存,大量的时间和内存都是在下面这句消耗的:

big_dict[key]->insert(line.substr(start, end));
2017-10-25 10:28:09 +08:00
回复了 scenix 创建的主题 C C++的 set 爆内存,求助
@jmc891205 @sagaxu 感谢二位回复,所以现在看来我存指针是完全错误的方向了。那么我直接存 string 对象作为 key,内存飞涨的问题怎么解决呢? 只有 600M 的文件读入,python 大概需要 800M 内存的样子,go 使用的更少。
目前我定义为
```c++
unordered_map<string, unordered_set<string>* > big_dict;`
```

存的时候
```c++
big_dict[key]->insert(line.substr(start, end)); //这样内存吃不消
```
2017-10-25 10:12:50 +08:00
回复了 scenix 创建的主题 C C++的 set 爆内存,求助
@03 感谢你的回复,我自然知道这段代码是实际上无法得到去重的效果的,我文中和代码注释中已经做了说明。原来 key 是直接存储的 string 对象,之所以存成指针是想着试试看光存指针会不会速度上来,结果这样改了下是不爆内存,但还是慢,就没心思管什么 const 不 const, 存成指针后里面东西还能不能用的问题了。
2017-10-25 10:06:36 +08:00
回复了 scenix 创建的主题 C C++的 set 爆内存,求助
@lcdtyph 首先感谢你的回复,我自然知道这段代码是实际上无法得到去重的效果的,我文中和代码注释中已经做了说明。我现在想解决的是运行的慢的问题,我重新定义 comp 函数能不能把速度提上来?请赐教。
用 Rsync 啊, 写个 Crontab 就行了
2016-10-26 17:51:38 +08:00
回复了 VicYu 创建的主题 剧集 看了 5 集的预告,越来越觉得 Dr. Robert Ford 就是机器人
@VicYu 乐园里的机器人都已经 pass 了图灵测试了,我记得剧情里说过,感觉迷宫应该是更高级别的测试。
2016-10-24 14:18:03 +08:00
回复了 lyver 创建的主题 推广 过节啦,领取好书一起 1024
《深入理解机器学习:从原理到算法》 直播的监管难度挺大的
我认为正确的工作流是这样:
1. dev 合并到 master
2. 删除 dev 分支
3. 从 master 上新建一个 dev 分支
2016-10-24 13:50:17 +08:00
回复了 Andor_Chen 创建的主题 CSS 送几本《CSS 实战手册(第四版)》
我是分母
1  2  3  4  5  6  7  8  9  10  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2727 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 26ms · UTC 08:13 · PVG 16:13 · LAX 00:13 · JFK 03:13
Developed with CodeLauncher
♥ Do have faith in what you're doing.