Так что я немного затруднен, потому что ни одно из решений не кажется теоретически оптимальным!
и
И, пожалуйста, не комментируйте «просто профилируйте это» - вопрос не в том, «что из этого лучше», а в «есть ли третий вариант»)
Ну, у большинства систем есть альтернативы fread
. Например, отображенные в память файлы, асинхронный ввод-вывод, read()
. Кроме того, обычно существует несколько способов «настроить» различные типы доступа к файлам, например, для файлов, отображаемых в память, вы можете заполнить весь файл.
Однако не существует единственного метода, который можно было бы считать решением лучше . Независимо от того, какой метод вы выберете, вы получите:
просто профиль
Для метода 1 вы пишете:
Это легко, но есть недостаток в том, что я выполняю вызов функции для fread () в каждом цикле.
Это вместе с «кажется теоретически оптимальным» является ключевым здесь. Вы делаете предположения без доказательств. Вы не можете просто судить о производительности, говоря «кажется».
Гадать о производительности исключительно, глядя на C-код, практически невозможно в современных компьютерных системах, где экстремальные оптимизации происходят как во время компиляции, так и при выполнении.
Откуда вы знаете, что вызов fread
для каждых 20 байтов является проблемой по сравнению с доступом к диску, который действительно медленный?
Опять, это возвращает вас к:
просто профиль
Ради интереса я сделал несколько простых тестов на своем Linux-компьютере, используя fread
с различным количеством nmemb. Программа прочитала файл 1G и вычислила простую промежуточную сумму, используя 1 байт в каждом считанном блоке.
Результаты, когда файл холодный (т.е. не кэшируется)
nmemb time (sec)
1 15.68
2 15.76
4 15.91
8 15.93
20 15.60
1000 15.60
Результаты, когда файл горячий (т.е. кэширован)
nmemb time (sec)
1 13.90
2 7.04
4 3.79
8 2.07
20 1.09
1000 0.42
Так что в моей системе размер блока (nmemb) не имеет значения, когда файл холодный. Для большинства приложений я бы назвал холодный файл «нормальным случаем», но наверняка есть приложения, которые могут читать один и тот же файл несколько раз.
Если файл горячий (т.е. кэшируется из-за предыдущих чтений), размер блока имеет значение. Но разница быстро уменьшается по мере увеличения размера блока. Уже в 20 против 1000 разница довольно мала.
Из вышесказанного я бы заключил: просто читайте 20 байтов каждый раз, чтобы сохранить код простым.
Все приведенные выше измерения / выводы действительны только для моей конкретной системы. Другая система может генерировать совершенно разные результаты в зависимости от типа / скорости процессора, дисковой системы и ОС.
Итак, еще раз, это возвращает нас к:
просто профиль