【问题标题】:How to retrieve data from a C file efficiently如何有效地从 C 文件中检索数据
【发布时间】:2017-08-07 20:38:29
【问题描述】:

我有一个程序应该从文本文件中检索(在启动时)数据。这个文件可能会变得很大,我想知道如何加快进程并评估其当前性能。 用于检索数据的代码如下:

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 库来测量检索所有所需数据所需的时间。 Bill 的数据分为 3 个文件:bills.db、workers.db 和 payment.db。 bills.dbpayments.db 中的每个文件行都代表一个完整的账单,而在 workers.db 中,代表账单所需的行数是可变的,并且取决于与账单相关的员工数量。

我以这种方式创建了这 3 个文件:

  • bills.dbpayments.db 有 118087 行(因此有多少账单)
  • 每张账单(任意)设置为有 4 个工人,因此,workers.db 文件有 118087*4 = 472348 行。

此函数完全运行所需的时间约为 0.9 秒。 这次有多好(或多坏)以及如何改进它?

【问题讨论】:

  • 顺便说一句,按顺序读取文件更快。也许这会有用stackoverflow.com/questions/42620323/…
  • 对我来说这很好。如果您以后必须处理较大的文件,您可能只想在启动时加载一部分,并在确实需要时加载其余部分(可能异步?)。不过使用 sql 数据库可能会更有效。
  • 如果性能很重要,为什么不使用 actual 数据库,例如 sqlite3?!
  • @Lovy 我只是想到了一个替代方案,那就是让一个线程在后台加载数据,这样用户在数据加载时就没有这个“无响应”的时间,但是我不太确定这是否真的有必要。
  • 可能会更快,你可以试试看是否更快。我无法确定,因为我不知道您的代码到底是做什么的。

标签: c performance file-io


【解决方案1】:

您必须阅读的内容很少。首先是渐近时间复杂度和渐近空间复杂度,其次是Big O notation。 Big O 表示法说明了程序的运行情况。对于您提供的代码,Big O 复杂度约为 O(n^2)。因此,最大限制很好,因为它与快速排序相同,但由于您使用的数据长度很长,因此加载时间将始终添加到您的运行时。如果您想改进,请尝试尽量减少数据长度从文件中读取最少的数据。因为如果 n 的值增加,时间将迅速增加。你可以从这里了解asymptotic notationBig O notation

【讨论】:

    猜你喜欢
    • 2017-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-17
    • 2022-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多