Пожалуйста, сообщите мне: есть ли более эффективный способ выполнения таких задач:
- Считывание пар ключ-значение из файла с разделителями первой вкладки в контейнер карты
- При чтении изфайл с разделителями во второй вкладке (пары «ключ-значение»), запись в третью
Выполнение этих двух шагов для fname1 и fname2 заняло 7 000 000 строк.
#include <string>
#include <map>
#include <fstream>
string col1;
int x;
map<string, int> m;
ifstream is1(fname1, ios::in | ios::binary);
ifstream is2(fname2, ios::in | ios::binary);
ofstream os3(fname3, ios::out | ios::binary);
if (is1.is_open())
{
while (is1 >> col1 >> x)
{
m[col1] = x;
}
is.close();
}
if (is2.is_open() && os3.is_open())
{
while (is2 >> col1 >> x)
{
if (m.count(col1) > 0)
x += m[col1];
os3 << col1 << "\t" << x << endl;
}
is2.close();
os3.close();
}
Что я сделал не так?Есть ли более эффективный способ выполнения таких задач?Или файловый ввод / вывод в большинстве случаев является узким местом?
ОБНОВЛЕНО: Здесь я приведу две реализации одного и того же алгоритма.Главный вопрос: почему pythonic версия работает быстрее ?Я решил переключиться на C ++, потому что слышал, что он обеспечивает более быстрый код.Был ли я не прав?
fname1, fname2 - ввод.fname3 - желаемый вывод.
fname1:
col1 col2 col3
1 1 1
2 2 2
fname2:
col1 col2 col3
1 1 2
3 3 3
fname3:
col1 col2 col3
1 13
2 2 2
3 3 3
def merge_two_files(fname1, fname2, fname3):
fout=open(fname3,'w')
fin1=open(fname1)
d1=dict()
for line in fin1:
l=line.strip().split('\t')
key='\t'.join(l[0:2])
d1[key] = float(l[2])
fin1.close()
d2=dict()
fin2=open(fname2)
for line in fin2:
l=line.strip().split('\t')
key='\t'.join(l[0:2])
d2[key] = float(l[2])
fin2.close()
for e in d1.viewkeys() & d2.viewkeys():
line_out='\t'.join([e,'{:.2f}'.format(d1[e]+d2[e])])
fout.write(line_out+'\n')
for e in d1.viewkeys() - (d1.viewkeys() & d2.viewkeys())
line_out='\t'.join([e,'{:.2f}'.format(d1[e])])
fout.write(line_out+'\n')
for e in d2.viewkeys() - (d1.viewkeys() & d2.viewkeys())
line_out='\t'.join([e,'{:.2f}'.format(d2[e])])
fout.write(line_out+'\n')
#include <fstream>
#include <string>
#include <unordered_map>
#include <set>
using namespace std;
int main() {
unordered_map < string, float > map1, map2 ;
set < string > s1, s2, both ;
string col1, col2, key, fname1, fname2, fname3 ;
float col3 ;
ifstream f1 ( fname1, ios::in | ios::binary) ;
ifstream f2 ( fname2, ios::in | ios::binary) ;
ofstream f3 ( fname3, ios::out | ios::binary) ;
if ( f1.is_open() ) {
while ( f1 >> col1 >> col2 >> col3 )
key= col1 + "\t" + col2 ;
map1.insert(make_pair(key,col3)) ;
s1.insert(key) ;
}
f1.close()
if ( f2.is_open() ) {
while ( f2 >> col1 >> col2 >> col3 ) {
key= col1 + "\t" + col2 ;
map2.insert(make_pair(key,col3)) ;
s2.insert(key) ;
}
}
f2.close() ;
set_intersection(s1.begin(), s1.end(),
s2.begin(), s2.end(),
inserter(both, both.begin())) ;
if ( f3.is_open() ) {
for ( const auto& e : both ) {
f3 << e << "\t" << map1.at(e) + map2.at(e) << "\n" ;
}
for ( const auto& kv : map1 ) {
if ( both.count(kv.first) ) continue ;
f3 << kv.first << "\t" << kv.second << "\n" ;
}
for ( const auto& kv : map2 ) {
if ( both.count(kv.first) ) continue ;
f3 << kv.first << "\t" << kv.second << "\n" ;
}
}
f3.close() ;
return 0;
}