Mam program, który łączy pętlę zagnieżdżania (link text). Zasadniczo to, co robi, czyta zawartość z pliku (powiedzmy plik 10GB) do bufora1 (powiedzmy 400 MB), umieszcza go w tabeli mieszającej. Teraz odczytaj zawartość drugiego pliku (powiedzmy plik 10GB) do bufora 2 (powiedzmy 100 MB) i zobacz, czy elementy w buforze2 są obecne w mieszaniu. Wyprowadzanie wyniku nie ma znaczenia. Po prostu interesuje mnie teraz wydajność programu. W tym programie muszę czytać 8 bajtów na raz z obu plików, więc używam długiego int. Problem polega na tym, że mój program jest bardzo nieefektywny. Jak mogę sprawić, by był wydajny?Dlaczego mój program jest wolny? Jak mogę poprawić jego efektywność?
// skompilować za pomocą g++ -o hash hash.c -std=c++0x
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <stdint.h>
#include <math.h>
#include <limits.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <unordered_map>
using namespace std;
typedef std::unordered_map<unsigned long long int, unsigned long long int> Mymap;
int main()
{
uint64_t block_size1 = (400*1024*1024)/sizeof(long long int); //block size of Table A - division operator used to make the block size 1 mb - refer line 26,27 malloc statements.
uint64_t block_size2 = (100*1024*1024)/sizeof(long long int); //block size of table B
int i=0,j=0, k=0;
uint64_t x,z,l=0;
unsigned long long int *buffer1 = (unsigned long long int *)malloc(block_size1 * sizeof(long long int));
unsigned long long int *buffer2 = (unsigned long long int *)malloc(block_size2 * sizeof(long long int));
Mymap c1 ; // Hash table
//Mymap::iterator it;
FILE *file1 = fopen64("10G1.bin","rb"); // Input is a binary file of 10 GB
FILE *file2 = fopen64("10G2.bin","rb");
printf("size of buffer1 : %llu \n", block_size1 * sizeof(long long int));
printf("size of buffer2 : %llu \n", block_size2 * sizeof(long long int));
while(!feof(file1))
{
k++;
printf("Iterations completed : %d \n",k);
fread(buffer1, sizeof(long long int), block_size1, file1); // Reading the contents into the memory block from first file
for (x=0;x< block_size1;x++)
c1.insert(Mymap::value_type(buffer1[x], x)); // inserting values into the hash table
// std::cout << "The size of the hash table is" << c1.size() * sizeof(Mymap::value_type) << "\n" << endl;
/* // display contents of the hash table
for (Mymap::const_iterator it = c1.begin();it != c1.end(); ++it)
std::cout << " [" << it->first << ", " << it->second << "]";
std::cout << std::endl;
*/
while(!feof(file2))
{
i++; // Counting the number of iterations
// printf("%d\n",i);
fread(buffer2, sizeof(long long int), block_size2, file2); // Reading the contents into the memory block from second file
for (z=0;z< block_size2;z++)
c1.find(buffer2[z]); // finding the element in hash table
// if((c1.find(buffer2[z]) != c1.end()) == true) //To check the correctness of the code
// l++;
// printf("The number of elements equal are : %llu\n",l); // If input files have exactly same contents "l" should print out the block_size2
// l=0;
}
rewind(file2);
c1.clear(); //clear the contents of the hash table
}
free(buffer1);
free(buffer2);
fclose(file1);
fclose(file2);
}
Aktualizacja:
Czy można bezpośrednio odczytać fragment (powiedzmy 400 MB) z pliku i bezpośrednio umieścić go w tabeli mieszania za pomocą C++ czytać strumień? Myślę, że może to jeszcze bardziej zmniejszyć obciążenie ogólne.
jak szybko powinien wyglądać program rozdrabniający 20G danych? – Timothy
Nie żartowałeś, gdy oznaczyłeś to jako C i C++. – Kevin
Kup szybszy dysk. Dyski SSD są miłe. –