LINUX.ORG.RU

[C] Чтение файла с помощью fgetc

 


0

1

Навеяно тредом про Exim. Решил я проверить, действительно ли всё так хорошо и поток байт из файла можно читать с помощью fgetc(), а буферы винта и ФС сами разрулят ситуацию.

Для проверки использовался следующий код:

#include <stdio.h>
#include <time.h>

int main() {
    const int n = 16384;
    char buf[n];

    time_t t1 = time(0);
    FILE* f = fopen("./1.avi","rb");
    while(!feof(f)) fgetc(f);//fread(buf,1,n,f);
    fclose(f);
    time_t t2 = time(0);

    printf("%i%,t2-t2);
    return 0;

Каждый раз брался новый файл, чтобы оно не кэшировалось слишком.

Использовалось две ОС: 1) Mandriva Linux 2011.0, ext3, размер блока 4096 2) MS Windows XP, NTFS, размер блока 4096

Таблицы экспериментов:

Mandriva, Ext3                              Windows, NTFS
метод | буфер | размер | время | мб/сек|    метод | буфер | размер | время | мб/сек|
---------------------------------------|    ---------------------------------------|
fgetc |     - |    264 |    12 |  22.0 |    fgetc |     - |    426 |    71 |   6.0 |
---------------------------------------|    ---------------------------------------|
fread |     1 |    441 |    39 |  11.3 |    fread |     1 |    426 |    71 |   6.0 |
      |     2 |    122 |     6 |  20.3 |          |     2 |    426 |    36 |  11.8 |
      |     4 |    183 |     6 |  30.5 |          |     4 |    497 |    29 |  17.1 |
      |     8 |    291 |     9 |  32.3 |          |     8 |    703 |    17 |  41.4 |
      |    16 |    273 |     8 |  34.1 |          |    16 |   1399 |    37 |  37.8 |
      |    32 |    834 |    18 |  46.3 |          |    32 |   1429 |    14 | 102.1 |
      |    64 |    740 |    17 |  43.5 |          |    64 |   1400 |    13 | 107.7 |
      |   128 |    889 |    20 |  44.5 |          |   128 |   1399 |    16 |  87.4 |
      |   256 |    622 |    14 |  44.4 |          |   256 |   1402 |    17 |  82.5 |
      |   512 |    734 |    13 |  56.5 |          |   512 |   1489 |    18 |  82.7 |
      |  1024 |    733 |    11 |  66.6 |          |  1024 |   4852 |    73 |  66.5 |
      |  2048 |    734 |    13 |  56.5 |          |  2048 |   4852 |    56 |  86.6 |
      |  4096 |    783 |    15 |  52.2 |          |  4096 |   4852 |    56 |  86.6 |
      |  8192 |    783 |    15 |  52.2 |          |  8192 |   4852 |    56 |  88.2 |
      | 16384 |    834 |    19 |  43.9 |          | 16384 |    834 |    56 |  86.6 |
---------------------------------------|    ---------------------------------------|

Выводы делайте сами.

★★★

Поясните данные в таблицах. Что означает время? И если время увеличилось, то значит скорость (мб/сек) уменьшилась.

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

> Поясните данные в таблицах. Что означает время? И если время увеличилось, то значит скорость (мб/сек) уменьшилась.

Время - количество секунд на обработку данных. Размер - объём данных (мб)

Sadler ★★★
() автор топика
Ответ на: комментарий от Sadler

> > Поясните данные в таблицах. Что означает время? И если время увеличилось, то значит скорость (мб/сек) уменьшилась.

Время - количество секунд на обработку данных. Размер - объём данных (мб)


Тогда поясните, как вы считали мб/сек.

ext3: 834 | 19 | 43.9
ntfs: 834 | 56 | 86.6

Почему при одном и том же объеме данных, у ntfs скорость в два раза выше, а время при этом почти в три раза больше. Что то я не уловлю логику расчетов.

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

> Почему при одном и том же объеме данных, у ntfs скорость в два раза выше, а время при этом почти в три раза больше. Что то я не уловлю логику расчетов.

834/19 = 43.9

Время разное потому, что разные машины, разные винты. Не надо сравнивать две таблицы (Windows и Linux), они получены с абсолютно разных машин.

Sadler ★★★
() автор топика
Ответ на: комментарий от andreyu

> ntfs: 834 | 56 | 86.6

Это я вообще не оттуда скопипастил значение. 4852 там

Sadler ★★★
() автор топика
Ответ на: комментарий от Sadler

> Время разное потому, что разные машины, разные винты. Не надо сравнивать две таблицы (Windows и Linux), они получены с абсолютно разных машин.

При чем тут разные машины и винты? 834 / 19 должнобыть больше, чем 834 / 56. По моему это очевидно.

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

> При чем тут разные машины и винты? 834 / 19 должнобыть больше, чем 834 / 56. По моему это очевидно.

Очевидно, что надо читать постом выше. Сообщение я уже исправить не могу.

Sadler ★★★
() автор топика
12 августа 2011 г.

Хоть и некропостинг, но добавлю: очень большие расходы при посимвольном чтении уходят на синхронизацию потоков - если заменить его на getc_unlocked, скорость увеличивается вдвое. Так что тормоза fgetc - это тормоза не посимвольного ввода, а потокобезопасности, которую требует POSIX (а не ISO C).

unsigned ★★★★
()
Ответ на: комментарий от Eddy_Em

Эту баянную задачу давно решил stdio (если под разделителем имеется в виду перевод строки)

оно когда читает файл построчно, потом делает llseek() назад, если прочитало слишком много. Вообще, для построчной работы с файлами ничего лучше stdin нету - максимально удобно. Впрочем, mmap - Тоже не плохо, но для реально больших текстовых файлов (ну типа, логи) могут начаться серьезные проблемы, особенно на 32-битных системах.

Насчёт посимвольного чтения (проверено, инфа 100%) ты больше всего потеряешь на вызове сисколлов, а никак не на чтении с винта.

Однако, в случае чтения строк из пайпа или сокета, баш, например, читает по одному символу, т.к. обязан гарантировать что не прочитает лишнего. Обратно засунуть не может, seek сделать не может, буфферизировать лишний остаток не может, ибо, возможно, остаток данных из файлового дескриптора должен будет прочитать другой процесс.

mmarkk
()
Ответ на: комментарий от Sadler

некроманов никто не отменял. впрочем, да, сорри. на дату не посмотрел чегото...

mmarkk
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.