0

    读入、输出优化

    2024.02.27 | admin | 66次围观

      在默认情况下, 是极为迟缓的读入/输出方式,而 比 快得多。

      下文将详细介绍读入输出的优化方法。

      这个函数是一个「是否兼容 stdio」的开关,C++ 为了兼容 C,保证程序在使用了 和 的时候不发生混乱,将输出流绑到了一起。同步的输出流是线程安全的。

      这其实是 C++ 为了兼容而采取的保守措施,也是使 / 速度较慢的主要原因。我们可以在进行 IO 操作之前将 stdio 解除绑定,但是在这样做之后要注意不能同时使用 和 ,也不能同时使用 和 ,但是可以同时使用 和 ,也可以同时使用 和 。

      tie 是将两个 stream 绑定的函数,空参数的话返回当前的输出流指针。

      在默认的情况下 绑定的是 ,每次执行 操作符的时候都要调用 来清理 stream buffer,这样会增加 IO 负担。可以通过 (0 表示 NULL)来解除 与 的绑定,进一步加快执行效率。

      但需要注意的是,在解除了 和 的绑定后,程序中必须手动 才能确保每次 展现的内容可以在 前出现。这是因为 被 buffer 为默认设置。例如:

      和 依然有优化的空间,这就是本章所介绍的内容——读入和输出优化。注意,本页面中介绍的读入和输出优化均针对整型数据,若要支持其他类型的数据(如浮点数),可自行按照本页面介绍的优化原理来编写代码。

      众所周知, 是用来读入 1 byte 的数据并将其转换为 类型的函数,且速度很快,故可以用「读入字符——转换为整型」来代替缓慢的读入

      每个整数由两部分组成——符号和数字

      整数的 '+' 通常是省略的,且不会对后面数字所代表的值产生影响,而 '-' 不可省略,因此要进行判定

    读入、输出优化

      10 进制整数中是不含空格或除 0~9 和正负号外的其他字符的,因此在读入不应存在于整数中的字符(通常为空格)时,就可以判定已经读入结束

      C 和 C++ 语言分别在 ctype.h 和 cctype 头文件中,提供了函数 , 这个函数会检查传入的参数是否为十进制数字字符,是则返回 true,否则返回 false。对应的,在下面的代码中,可以使用 代替 ,也可以使用 代替 举例

      读入 num 可写为

      同样是众所周知, 是用来输出单个字符的函数

      因此将数字的每一位转化为字符输出以加速

      要注意的是,负号要单独判断输出,并且每次 %(mod)取出的是数字末位,因此要倒序输出

      但是递归实现常数是较大的,我们可以写一个栈来实现这个过程举例

      输出 num 可写为

      通过 或者 可以实现更快的读入。

      能将需要的文件部分读入内存缓冲区。 则会调度内核级函数,将文件一次性地映射到内存中,类似于可以指针引用的内存区域。所以在日常程序读写时,只需要重复读取部分文件可以使用 ,因为如果用 反复读取一小块文件,做一次性内存映射并且内核处理 page fault 的花费会远比使用 的内核级函数调度大。

      一次性读入缓冲区的操作比逐个字符读入(,)要快的多。因为硬盘的多次读写速度是要慢于直接读取内存的,所以先一次性读到缓存区里再从缓存区读入要快的多。并且 确保了进程间自动共享,存储区如果可以也会与内核缓存分享信息,确保了更少的拷贝操作。

      更通用的是 ,因为 不能在 Windows 环境下使用(例如 CodeForces 的 tester)。

      类似于参数为 的 ,不过它更为快速,而且可以一次性读入若干个字符(包括空格换行等制表符),如果缓存区足够大,甚至可以一次性读入整个文件。

      对于输出,我们还有对应的 函数

      使用示例:,表示从 stdin 文件流中读入 SIZE 个大小为 1 byte 的数据块到 Buf 中。

      读入之后的使用就跟普通的读入优化相似了,只需要重定义一下 getchar。它原来是从文件中读入一个 char,现在变成从 Buf 中读入一个 char,也就是头指针向后移动一位。

      也是类似的,先放入一个 中,最后通过 一次性将 输出。

      参考代码:

      和 是有缓冲区的。这也就是为什么,如果输入函数紧跟在输出函数之后/输出函数紧跟在输入函数之后可能导致错误。程序结束关闭文件 输出 或者 到终端的时候(注:如果是输出到文件,则不会刷新缓冲区)手动 缓冲区满自动刷新 输出

      如果你的程序使用多个类型的变量,那么可能需要写多个输入输出优化的函数。下面给出的代码使用 C++ 中的 实现了对于所有整数类型的输入输出优化。

      如果要分别输入 类型的变量 a, 类型的变量 b 和 类型的变量 c,那么可以写成

      关闭调试开关时使用 ,,退出时自动析构执行 。

      开启调试开关时使用 ,,便于调试。

      若要开启文件读写时,请在所有读写之前加入 。

      http://www.hankcs.com/program/cpp/cin-tie-with-sync_with_stdio-acceleration-input-and-output.html

      http://meme.biology.tohoku.ac.jp/students/iwasaki/cxx/speed.html

      https://marc.info/?l=linux-kernel&m=95496636207616&w=2

    版权声明

    本文仅代表作者观点,不代表xx立场。
    本文系作者授权xxx发表,未经许可,不得转载。

    发表评论