词法分析器中的文件缓冲:是否可取,现在操作系统(和语言库)已在内部实现缓冲区?

时间:2018-04-26 03:12:35

标签: compiler-construction

在两本书中提到了词法分析器优化技术:由K.Cooper等人设计编译器。和C.Fischer等编写的编译器。这是第一本书(第69页)的除外:

  

虽然逐字符I / O导致干净的算法公式,但每个字符的过程调用的开销相对于在表驱动或直接编码扫描器中模拟DFA的成本是显着的。为了降低每个字符的I / O成本,编译器编写器可以使用缓冲I / O,其中每个读取操作返回更长的字符串或缓冲区,然后扫描程序通过缓冲区进行索引。扫描仪保持指向缓冲区的指针......

我的问题是,这种技术有什么意义?现在内存缓冲通常已经由操作系统实现,为什么作者建议我们实现缓冲? (此外,高级语言提供的标准库通常具有使用文件流处理例程维护的缓冲区,如C ++的std :: ifstream)。

我知道在一些应用程序中,如数据库系统,自定义缓冲机制不仅是可取的(更多地了解访问模式),但有时是必要的(恢复,日志记录)。类似的reasongs是否适用于编译器中的词法分析器?如果是这样,怎么样?

修改: 这是一个类似的问题:link,但我想更多地了解自定义缓冲区的参数(如支持数据库系统中的缓冲区的参数),如果有的话。

另一篇文章here将手动缓冲与C ++中的std :: fstream缓冲进行了比较。

2 个答案:

答案 0 :(得分:1)

正如其他人所指出的那样,无论操作系统是否缓冲(确实如此),您的应用程序依赖它都是非常昂贵的,因为那些OS /文件系统缓冲区不在您的应用程序地址空间中。为什么?因为您的应用程序需要获取该数据,所以通常需要通过多层调用来访问OS缓冲区。如果您一次为1个字符/字节执行此操作,则会产生开销。

如果您正在使用IO库:由于性能原因,其中一些会执行或将“提前”读取,并将操作系统调用保持在最低限度。

另一方面,如果您在不利用库的情况下进行操作,则强烈建议您设置缓冲IO功能,原因与其他库相同。

最后,编译的最终结果是可执行的东西。除非您不允许IO发生,否则您将希望具有特定语言(假设自托管)运行时以提供缓冲IO,原因相同。如果您的运行时基于提供它的一种语言或一系列库,那么您应该很好。

答案 1 :(得分:1)

  

类似的原因是否适用于编译器中的词法分析器?

有时,当然。例如,考虑一个词法分析器规则,它返回一个标记,表示"这是一个变量名称"。解析器不仅需要"是一个变量名称"令牌本身,但也是实际名称:如果不知道名称是Fred,Wilma,还是Barney,或其他什么,知道这是一个名称是没有用的。

如果 是一个名称,那么该名称应该存储在哪里?您是否可以直接授予解析器访问名称本身的字节流? (如果是这样,持续多长时间?解析器需要多长时间?)

或考虑字符串文字(使用这些语法)。构成字符串的字符存储在哪里?你能直接授予对原始缓冲区的访问权限吗?

如果您拥有提供这些扫描时缓冲区的数据结构,那么可以授予对它们的有限访问权限,并确切地知道借用字符​​串的生命周期。这可能会取决于更多细节,让您避免复制(至少有时)。如果您正在使用一些库提供的缓冲I / O例程,这些例程一次只能提供一个字符,那么您肯定无法授予此类访问权限。