Rumah > Soal Jawab > teks badan
Saya perlu membaca 50 juta data berganda daripada fail txt dan menyimpannya dalam vektor pada mulanya saya fikir fail io mungkin terlalu perlahan, jadi saya menggunakan pemetaan memori fail untuk membaca kandungan fail ke dalam memori sebagai blok ke dalam vektor satu demi satu, tetapi membaca data terus dari fail satu demi satu hanya mengambil masa 3 minit Selepas saya mengoptimumkannya, ia meningkat kepada 5 minit.
Pelan pengoptimuman saya adalah untuk membaca keseluruhan fail ke dalam memori, memasukkannya ke dalam penimbal char*, dan kemudian menggunakan vec_name.reserve(50000000); untuk memperuntukkan 50 juta kapasiti untuk mengelakkan peruntukan memori berulang, tetapi ia nampaknya tidak memberi kesan.
Adakah kerana masa dihabiskan terutamanya untuk push_back?
Adakah terdapat kaedah pengoptimuman yang baik? Terima kasih semua!
Kod kunci yang dioptimumkan adalah seperti berikut: (ia mengambil masa lima minit untuk membaca semua data ke dalam vektor)
ifstream iVecSim("input.txt");
iVecSim.seekg(0, iVecSim.end);
long long file_size = iVecSim.tellg();//文件大小
iVecSim.seekg(0, iVecSim.beg);
char *buffer = new char[file_size];
iVecSim.read(buffer, file_size);
string input(buffer);
delete[]buffer;
istringstream ss_sim(input);//string流
string fVecSim;
vec_similarity.reserve(50000000);
while (ss_sim.good()) {//从string流中读入vector
ss_sim >> fVecSim;
vec_similarity.push_back(atof(fVecSim.c_str()));
}
漂亮男人2017-05-31 10:38:40
Tidak masuk akal untuk dijalankan dalam mod nyahpepijat Apabila saya menggunakan kod anda untuk dijalankan dalam mod keluaran, ia hanya mengambil masa kira-kira 14 saat.
Untuk menyelesaikan masalah, cari masalah dahulu saya ubah suai kod seperti ini dan ketahui dahulu di mana masa dihabiskan
.std::cout << "Start" << std::endl;
auto n1 = ::GetTickCount();
auto n2 = 0;
auto n3 = 0;
auto n4 = 0;
while (ss_sim.good())
{
auto n = ::GetTickCount();
ss_sim >> fVecSim;
n2 += (::GetTickCount() - n);
n = ::GetTickCount();
auto v = atof(fVecSim.c_str());
n3 += (::GetTickCount() - n);
n = ::GetTickCount();
vec_similarity.push_back(v);
n4 += (::GetTickCount() - n);
}
n1 = ::GetTickCount() - n1;
std::cout << "ss_sim >> fVecSim:" << n2 << "ms" << std::endl;
std::cout << "atof:" << n3 << "ms" << std::endl;
std::cout << "push_back:" << n4 << "ms" << std::endl;
std::cout << "Total:" << n1 << "ms" << std::endl;
Jadi kesesakan terletak pada ayat "ss_sim >> fVecSim". atof cukup pantas.
Jadi kesimpulan saya ialah: penyelesaian pengoptimuman muktamad adalah untuk memulakan dengan format storan dan menyimpan data anda sebagai binari dan bukannya rentetan, dengan itu mengelakkan overhed rentetan IO dan fungsi penukaran benar-benar dalam beberapa saat .
phpcn_u15822017-05-31 10:38:40
Cara paling berkesan pada masa ini ialah menggunakan strim, dan ia boleh dilihat daripada pelaksanaan kod anda: anda membaca semua kandungan fail ke dalam penimbal sekaligus, yang bukan cara terbaik. Adalah disyorkan untuk membaca penimbal[1024] secara purata setiap kali, iaitu 1K atau nilai lain. Selepas membaca, penunjuk bergerak ke baris seterusnya dan meneruskan bacaan sehingga tamat kedudukan EOF
天蓬老师2017-05-31 10:38:40
1. Jika tiada pergantungan antara data, anda boleh mencuba bacaan berbilang benang dalam blok
2 Selain itu, ingatan vektor adalah berterusan. agak ramai.
天蓬老师2017-05-31 10:38:40
Anda boleh bertukar kepada gaya C scanf
cuba
Wah, kenapa awak layan jawapan saya begini? Netizen yang melaporkan saya ingin bertanya, kenapa ada yang tidak kena dengan jawapan ini?