Я пытаюсь прочитать большой набор данных, отформатировать его так, как мне нужно, а затем записать его в другой файл. Я пытаюсь использовать C ++ поверх SAS или STATA для увеличения скорости. Файл данных обычно составляет около 10 гигабайт. И мой текущий код выполняется более часа (а потом я его убиваю, потому что уверен, что с моим кодом что-то очень неэффективно).
Есть ли более эффективный способ сделать это? Может быть, прочитать файл в память, а затем проанализировать его с помощью операторов switch? (У меня есть 32 ГБ оперативной памяти Linux 64bit). Возможно ли, что чтение, а затем запись в цикле замедляет его, поскольку оно постоянно читает, а затем пишет? Я попытался прочитать его с одного диска, а затем записать на другой, чтобы ускорить процесс.
Случаи переключателя замедляют это?
Процесс, который у меня есть, теперь читает данные с помощью getline, использует оператор switch для правильного анализа, а затем записывает их в мой outfile. И повторяется за 300 миллионов строк. В операторе switch есть еще около 10 случаев, но я для краткости не копировал.
Код, вероятно, очень уродлив, потому что находится в основной функции, но я хотел, чтобы он работал, прежде чем я начал работать над привлекательностью.
Я пытался использовать read (), но безуспешно. Пожалуйста, дайте мне знать, если мне нужно что-то уточнить.
Спасибо вам за помощь!
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <stdio.h>
//#include <cstring>
//#include <boost/algorithm/string.hpp>
#include <vector>
using namespace std;
//using namespace boost;struct dataline
{
char type[0];
double second;
short mill;
char event[1];
char ticker[6];
char marketCategory[1];
char financialStatus[1];
int roundLotSize;
short roundLotOnly;
char tradingState[1];
char reserved[1];
char reason[4];
char mpid[4];
char primaryMarketMaker[1];
char primaryMarketMode[1];
char marketParticipantState[1];
unsigned long orderNumber;
char buySell[0];
double shares;
float price;
int executedShares;
double matchNumber;
char printable[1];
double executionPrice;
int canceledShares;
double sharesBig;
double crossPrice;
char crossType[0];
double pairedShares;
double imbalanceShares;
char imbalanceDirection[1];
double fairPrice;
double nearPrice;
double currentReferencePrice;
char priceVariationIndicator[1];
};
int main ()
{
string a;
string b;
string c;
string d;
string e;
string f;
string g;
string h;
string k;
string l;
string times;
string smalltimes;
short time; //counter to keep second filled
short smalltime; //counter to keep millisecond filled
double N;
double NN;
double NNN;
int length;
char M;
//vector<> fout;
string line;
ofstream fout ("/media/3tb/test.txt");
ifstream myfile;
myfile.open("S050508-v3.txt");
dataline oneline;
if (myfile.is_open())
{
while ( myfile.good() )
{
getline (myfile,line);
// cout << line<<endl;;
a=line.substr(0,1);
stringstream ss(a);
char type;
ss>>type;switch (type)
{
case 'T':
{
if (type == 'T')
{
times=line.substr(1,5);
stringstream s(times);
s>>time;
//oneline.second=time;
//oneline.second;
//cout<<time<<endl;
}
else
{
time=time;
}
break;
}
case 'M':
{
if (type == 'M')
{
smalltimes=line.substr(1,3);
stringstream ss(smalltimes);
ss>>smalltime; //oneline.mill;
// cout<<smalltime<<endl; //smalltime=oneline.mill;
}
else
{
smalltime=smalltime;
}
break;
}case 'R':
{
oneline.second=time;
oneline.mill=smalltime;
a=line.substr(0,1);
stringstream ss(a);
ss>>oneline.type;
b=line.substr(1,6);
stringstream sss(b);
sss>>oneline.ticker;
c=line.substr(7,1);
stringstream ssss(c);
ssss>>oneline.marketCategory;
d=line.substr(8,1);
stringstream sssss(d);
sssss>>oneline.financialStatus;
e=line.substr(9,6);
stringstream ssssss(e);
ssssss>>oneline.roundLotSize;
f=line.substr(15,1);
stringstream sssssss(f);
sssssss>>oneline.roundLotOnly;
*oneline.tradingState=0;
*oneline.reserved=0;
*oneline.reason=0;
*oneline.mpid=0;
*oneline.primaryMarketMaker=0;
*oneline.primaryMarketMode=0;
*oneline.marketParticipantState=0;
oneline.orderNumber=0;
*oneline.buySell=0;
oneline.shares=0;
oneline.price=0;
oneline.executedShares=0;
oneline.matchNumber=0;
*oneline.printable=0;
oneline.executionPrice=0;
oneline.canceledShares=0;
oneline.sharesBig=0;
oneline.crossPrice=0;
*oneline.crossType=0;
oneline.pairedShares=0;
oneline.imbalanceShares=0;
*oneline.imbalanceDirection=0;
oneline.fairPrice=0;
oneline.nearPrice=0;
oneline.currentReferencePrice=0;
*oneline.priceVariationIndicator=0;
break;
}//End Case
}//End Switch
}//end While
myfile.close();
}//End If
else cout << "Unable to open file";
cout<<"Junk"<<endl;
return 0;
}
ОБНОВИТЬ Итак, я пытался использовать карту памяти, но теперь у меня ошибка сегментации.
Я пытался следовать различным примерам, чтобы собрать воедино то, что сработало бы для меня. Почему я получаю ошибку сегментации? Я взял первую часть своего кода, которая выглядит так:
int main (int argc, char** path)
{
long i;
int fd;
char *map;
char *FILEPATH = path;
unsigned long FILESIZE;
FILE* fp = fopen(FILEPATH, "/home/brian/Desktop/S050508-v3.txt");
fseek(fp, 0, SEEK_END);
FILESIZE = ftell(fp);
fseek(fp, 0, SEEK_SET);
fclose(fp);
fd = open(FILEPATH, O_RDONLY);
map = (char *) mmap(0, FILESIZE, PROT_READ, MAP_SHARED, fd, 0);
char z;
stringstream ss;
for (long i = 0; i <= FILESIZE; ++i)
{
z = map[i];
if (z != '\n')
{
ss << z;
}
else
{
// c style tokenizing
ss.str("");
}
}
if (munmap(map, FILESIZE) == -1) perror("Error un-mmapping the file");
close(fd);
Файл данных обычно составляет около 10 гигабайт.
…
Случаи переключателя замедляют это?
Почти наверняка нет, пахнет, как будто вы связаны с I / O. Но вы должны подумать об этом. Современные процессоры имеют счетчики производительности, которые довольно легко использовать с правильными инструментами. Но давайте начнем разбивать проблемы на несколько основных областей: ввод-вывод на устройства, загрузка / сохранение в памяти, процессор. Вы можете поместить некоторые маркеры в свой код, где вы читаете часы, чтобы понять, сколько времени занимает каждая из операций. На linux
ты можешь использовать clock_gettime()
или rdtsc
инструкция для доступа к часам с большей точностью, чем тик ОС.
Рассматривать mmap
/CreateFileMapping
любой из которых может обеспечить лучшую эффективность / пропускную способность для страниц, к которым вы обращаетесь.
Рассматривайте большие / огромные страницы при потоковой передаче через большие объемы данных, которые уже были разбиты на страницы.
Описание
mmap () создает новое отображение в виртуальном адресном пространстве
вызывающий процесс. Начальный адрес для нового сопоставления указан
в адрес Аргумент длины указывает длину отображения.
Вот mmap()
пример:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#define FILEPATH "/tmp/mmapped.bin"#define NUMINTS (1000)
#define FILESIZE (NUMINTS * sizeof(int))
int main(int argc, char *argv[])
{
int i;
int fd;
int *map; /* mmapped array of int's */
fd = open(FILEPATH, O_RDONLY);
if (fd == -1) {
perror("Error opening file for reading");
exit(EXIT_FAILURE);
}
map = mmap(0, FILESIZE, PROT_READ, MAP_SHARED, fd, 0);
if (map == MAP_FAILED) {
close(fd);
perror("Error mmapping the file");
exit(EXIT_FAILURE);
}
/* Read the file int-by-int from the mmap
*/
for (i = 1; i <=NUMINTS; ++i) {
printf("%d: %d\n", i, map[i]);
}
if (munmap(map, FILESIZE) == -1) {
perror("Error un-mmapping the file");
}
close(fd);
return 0;
}
Других решений пока нет …