Последнее обновление: мой одноклассник использует fread() для чтения около трети всего файла в строке, это может избежать нехватки памяти. Затем обработайте эту строку, отделите эту строку в своей структуре данных. Обратите внимание, что вам нужно заботиться об одной проблеме: в конце этой строки эти последние несколько символов могут не состоять из одного целого числа. Подумайте об одном способе обнаружить эту ситуацию, чтобы вы могли подключить эти символы к первым нескольким символам следующей строки.
Каждое число соответствует переменной в вашей структуре данных. Ваша структура данных должна быть очень простой, потому что каждый раз, если вы вставляете свои данные в одну структуру данных, она очень медленная. Большая часть времени тратится на вставку данных в структуру данных. Поэтому самый быстрый способ обработки этих данных: использовать fread() для чтения этого файла в строку, разделить эту строку на разные одномерные массивы.
Например (просто пример, не из моего проекта), у меня есть текстовый файл, например:
72 24 20
22 14 30
23 35 40
42 29 50
19 22 60
18 64 70
.
.
.
Каждая строка - это информация одного человека. Первая колонка означает возраст человека, второй столбец - его депозит, второй - возраст его жены.
Затем мы используем fread() для чтения этого текстового файла в строку, затем я использую stroke() для его разделения (вы можете использовать более быстрый способ его разделить).
Не используйте структуру данных для хранения разделенных данных!
Я имею в виду, не делайте этого:
struct person
{
int age;
int deposit;
int wife_age;
};
struct person *my_data_store;
my_data_store=malloc(sizeof(struct person)*length_of_this_array);
//then insert separated data into my_data_store
Не используйте структуру данных для хранения данных! Самый быстрый способ хранения ваших данных:
int *age;
int *deposit;
int *wife_age;
age=(int*)malloc(sizeof(int)*age_array_length);
deposit=(int*)malloc(sizeof(int)*deposit_array_length);
wife_age=(int*)malloc(sizeof(int)*wife_array_length);
// the value of age_array_length,deposit_array_length and wife_array_length will be known by using `wc -l`.You can use wc -l to get the value in your C program
// then you can insert separated data into these arrays when you use `stroke()` to separate them.
Второе обновление: лучший способ - использовать freed() для чтения части файла в строку, а затем разделить эту строку на вашу структуру данных. Кстати, не используйте никакую стандартную библиотечную функцию, которая может форматировать строку в целое число, чтобы замедлить, например fscanf() or atoi(), мы должны написать нашу собственную функцию, чтобы перенести строку в n целое число. Не только это, мы должны разработать более простую структуру данных для хранения этих данных. Кстати, мой одноклассник может прочитать этот файл 1.7G в течение 7 секунд. Есть способ сделать это. Этот способ намного лучше, чем использование многопоточности. Я не вижу его кода, после того как я увижу его код, я обновлю третий раз, чтобы рассказать вам, как это сделать. Это будет через два месяца после завершения нашего курса.
Обновление: я использую multithread для решения этой проблемы! Оно работает! Обратите внимание: не используйте clock() для вычисления времени использования многопоточности, поэтому я думал, что время выполнения увеличивается.
Одна вещь, которую я хочу уточнить, заключается в том, что время чтения файла без сохранения значения в моей структуре составляет около 20 секунд. Время хранения значения в моей структуре составляет около 60 секунд. Определение "время чтения файла" включает время чтения всего файла и сохранение значения в моей структуре. время чтения файла = сканировать файл + сохранить значение в моей структуре. Поэтому, есть некоторые предложения по сохранению ценности быстрее? (Кстати, у меня нет контроля над inout файлом, он создается нашим профессором. Я пытаюсь использовать многопоточность для решения этой проблемы, если она работает, я расскажу вам результат.)
У меня есть файл, его размер равен 1.7G. Это выглядит так:
1 1427826
1 1427827
1 1750238
1 2
2 3
2 4
3 5
3 6
10 7
11 794106
.
.
и сын.
В файле содержится около десяти миллионов строк. Теперь мне нужно прочитать этот файл и сохранить эти цифры в моей структуре данных в течение 15 секунд.
Я попытался использовать freed() для чтения целого файла, а затем использовать strtok() для разделения каждого номера, но для него все еще требуется 80 секунд. Если я использую fscanf(), он будет медленнее. Как мне это ускорить? Возможно, мы не сможем сделать это менее 15 секунд. Но 80 секунд, чтобы прочитать это слишком долго. Как читать это так быстро, как мы можем?
Вот часть моего кода чтения:
int Read_File(FILE *fd,int round)
{
clock_t start_read = clock();
int first,second;
first=0;
second=0;
fseek(fd,0,SEEK_END);
long int fileSize=ftell(fd);
fseek(fd,0,SEEK_SET);
char * buffer=(char *)malloc(sizeof(char)*fileSize);
char *string_first;
long int newFileSize=fread(buffer,1,fileSize,fd);
char *string_second;
while(string_first!=NULL)
{
first=atoi(string_first);
string_second=strtok(NULL," \t\n");
second=atoi(string_second);
string_first=strtok(NULL," \t\n");
max_num= first > max_num ? first : max_num ;
max_num= second > max_num ? second : max_num ;
root_level=first/NUM_OF_EACH_LEVEL;
leaf_addr=first%NUM_OF_EACH_LEVEL;
if(root_addr[root_level][leaf_addr].node_value!=first)
{
root_addr[root_level][leaf_addr].node_value=first;
root_addr[root_level][leaf_addr].head=(Neighbor *)malloc(sizeof(Neighbor));
root_addr[root_level][leaf_addr].tail=(Neighbor *)malloc(sizeof(Neighbor));
root_addr[root_level][leaf_addr].g_credit[0]=1;
root_addr[root_level][leaf_addr].head->neighbor_value=second;
root_addr[root_level][leaf_addr].head->next=NULL;
root_addr[root_level][leaf_addr].tail=root_addr[root_level][leaf_addr].head;
root_addr[root_level][leaf_addr].degree=1;
}
else
{
//insert its new neighbor
Neighbor *newNeighbor;
newNeighbor=(Neighbor*)malloc(sizeof(Neighbor));
newNeighbor->neighbor_value=second;
root_addr[root_level][leaf_addr].tail->next=newNeighbor;
root_addr[root_level][leaf_addr].tail=newNeighbor;
root_addr[root_level][leaf_addr].degree++;
}
root_level=second/NUM_OF_EACH_LEVEL;
leaf_addr=second%NUM_OF_EACH_LEVEL;
if(root_addr[root_level][leaf_addr].node_value!=second)
{
root_addr[root_level][leaf_addr].node_value=second;
root_addr[root_level][leaf_addr].head=(Neighbor *)malloc(sizeof(Neighbor));
root_addr[root_level][leaf_addr].tail=(Neighbor *)malloc(sizeof(Neighbor));
root_addr[root_level][leaf_addr].head->neighbor_value=first;
root_addr[root_level][leaf_addr].head->next=NULL;
root_addr[root_level][leaf_addr].tail=root_addr[root_level][leaf_addr].head;
root_addr[root_level][leaf_addr].degree=1;
root_addr[root_level][leaf_addr].g_credit[0]=1;
}
else
{
//insert its new neighbor
Neighbor *newNeighbor;
newNeighbor=(Neighbor*)malloc(sizeof(Neighbor));
newNeighbor->neighbor_value=first;
root_addr[root_level][leaf_addr].tail->next=newNeighbor;
root_addr[root_level][leaf_addr].tail=newNeighbor;
root_addr[root_level][leaf_addr].degree++;
}
}