2017-08-07 37 views
3

我有一個應該從文本文件中檢索(啓動時)數據的程序。這個文件可能會變得很大,我想知道如何加快這個過程並評估它的當前性能。 用於檢索數據的代碼如下:如何有效地從C文件中檢索數據

void startUpBillsLoading(Bill *Bills) 
{ 
    FILE *BillsDb = 0, *WorkersDb = 0, *PaymentDb = 0; 
    BillsDb = fopen("data/bills.db", "r"); 
    WorkersDb = fopen("data/workers.db", "r"); 
    PaymentDb = fopen ("data/payments.db", "r"); 
    char *Buffer = malloc (512); 

    if (BillsDb && WorkersDb && PaymentsDb) 
    { 
     int i = 0, j = 0; 

     while (fscanf (BillsDb, "%d;%[^;];%[^;];%[^;];%[^;];%d/%d/%d;%d/%d/%d;%d;%f;%f\n", 
       &Bills[i].Id, 
       Bills[i].CompanyName, 
       Bills[i].ClientName, 
       Bills[i].DepartureAddress, 
       Bills[i].ShippingAddress, 
       &Bills[i].Creation.Day, 
       &Bills[i].Creation.Month, 
       &Bills[i].Creation.Year, 
       &Bills[i].Payment.Day, 
       &Bills[i].Payment.Month, 
       &Bills[i].Payment.Year, 
       &Bills[i].NumWorkers, 
       &Bills[i].TotalHT, 
       &Bills[i].Charges) == 14) 
     { 
      Bills[i].Workers = 
       malloc (sizeof(Employee)*Bills[i].NumWorkers); 

      fscanf (PaymentDb, "%d;%d;%[^;];%[^;];%[^\n]\n", 
        &Bills[i].Id, 
        &Bills[i].PaymentDetails.Method, 
        Bills[i].PaymentDetails.CheckNumber, 
        Bills[i].PaymentDetails.VirementNumber, 
        Bills[i].PaymentDetails.BankName); 

      LatestBillId++; 
      i++; 
     } 

     i = 0; 
     while (fscanf (WorkersDb, "%d;%[^;];%[^;];%f\n", 
        &Bills[i].Id, 
        Bills[i].Workers[j].Surname, 
        Bills[i].Workers[j].Name, 
        &Bills[i].Workers[j].Salary) == 4) 
     { 
      for (int j = 1; j <= Bills[i].NumWorkers-1; j++) 
      { 
       fscanf (WorkersDb, "%d;%[^;];%[^;];%f\n", 
           &Bills[i].Id, 
           Bills[i].Workers[j].Surname, 
           Bills[i].Workers[j].Name, 
           &Bills[i].Workers[j].Salary); 
      } 
      i++; 
     } 

     fclose(BillsDb); 
     fclose(WorkersDb); 
     fclose(PaymentDb); 
    } 
    else 
     printf ("\t\t\tImpossible d'acceder aux factures !\n"); 

    free (Buffer); 
} 

我已經使用了time.h庫來衡量它需要檢索所有需要的數據的時間。 賬單數據分爲3個文件:bills.db,workers.db和payments.db。來自bills.dbpayments.db的每個文件行代表整個賬單,而在workers.db代表賬單所需的行數是可變的並且取決於與賬單相關的僱員數量。

我以這種方式創建這3個文件:

  • bills.dbpayments.db有118087行(從而儘可能多的票據)
  • 每個法案設定(任意)有4名所以工人,workers.db文件有118087 * 4 = 472348行。

此函數完全運行所用的時間約爲0.9秒。 這次有多好(或差),以及如何改善?

+1

只是一個側面說明,按順序讀取文件更快。也許這將是有用的https://stackoverflow.com/questions/42620323/why-is-reading-multiple-files-at-the-same-time-slower-than-reading-serialtially –

+0

對我來說它是好的,因爲它是。如果以後必須處理較大的文件,則可能只需要在啓動時加載一部分,並在真正需要時加載其餘部分(mayne異步?)。使用sql數據庫可能會更有效。 – Lovy

+2

如果性能很重要,爲什麼不使用* actual *數據庫,如sqlite3 ?! –

回答

0

有幾件事你必須閱讀。首先是一個漸近時間複雜度和漸近空間複雜度和第二個是大O表示法。大O符號表明程序的工作效果如何。對於您提供的代碼,大O複雜度爲O(n^2) aprox。因此,最大限制是好的,因爲它與快速排序相同,但由於您使用的數據有很多長度,加載時間將始終添加到運行時。如果你想改進嘗試最小化你的數據的長度從文件中讀取最少。因爲如果n值的增加時間會迅速增加。你可以從這裏閱讀約asymptotic notationBig O notation