13.07.2015 Views

Perl 语言编程 - Linux教程

Perl 语言编程 - Linux教程

Perl 语言编程 - Linux教程

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

这 个 回 合 是 可 选 的 ; 在 普 通 的 情 况 下 并 不 出 现 这 个 回 合 。 但 是 , 如 果 调 用 了 任 何 三个 代 码 生 成 器 之 一 ——B::Bytecode,B::C, 和 B::CC, 那 么 就 会 最 后 再 访 问 一 次 分析 树 。 代 码 生 成 器 要 么 发 出 用 于 稍 后 重 新 构 造 分 析 树 的 串 行 的 <strong>Perl</strong> 字 节 码 , 要 么 是 代表 编 译 时 分 析 树 状 态 的 文 本 C 代 码 。C 代 码 的 生 成 源 自 两 种 不 同 的 风 格 。B::C 简 单 地 重 新 构 造 分 析 树 , 然 后 用 <strong>Perl</strong> 在执 行 的 时 候 自 己 用 的 普 通 的 runops() 循 环 运 行 之 。B::CC 生 成 一 个 线 性 化 了 并 且 优化 过 的 运 行 时 代 码 路 径 ( 组 成 一 个 巨 大 的 跳 转 表 ) 的 C 等 效 物 , 并 且 执 行 之 。在 编 译 的 时 候 ,<strong>Perl</strong> 用 许 多 方 法 优 化 你 的 代 码 。 它 重 新 排 列 代 码 好 让 它 在 运 行 时 更 有 效 。它 删 除 那 些 在 执 行 时 可 能 永 远 不 会 到 达 的 代 码 , 比 如 一 个 if(0) 块 , 或 者 在 if (1) 块 里 的elsif 和 else。 如 果 你 使 用 用 my ClassName ? $var 或 our ClassName ? $var 声 明 的词 法 类 型 , 而 且 ClassName ? 包 是 用 use fields 用 法 设 置 的 , 那 么 对 下 层 的 伪 哈 希 的 常量 域 的 访 问 会 在 编 译 时 进 行 拼 写 检 查 并 且 转 换 成 一 个 数 组 访 问 。 如 果 你 给 sort 操 作 符 一 个足 够 简 单 的 比 较 路 径 , 比 如 {$a $b} 或 者 {$b cmp $a}, 那 么 它 会 被 一 个 编 译 好的 C 代 码 代 替 。<strong>Perl</strong> 里 最 富 戏 剧 性 的 优 化 可 能 就 是 它 尽 可 能 快 地 解 析 常 量 表 达 式 的 方 法 。 比 如 , 让 我 们 看看 图 18-2 的 分 析 树 。 如 果 节 点 1 和 2 都 有 文 本 和 常 量 函 数 , 节 点 1 到 4 将 已 经 被 那些 计 算 代 替 了 , 就 象 图 18-3 的 分 析 树 :图 18-3 ( 略 。。。)这 就 叫 常 量 消 除 。 常 量 消 除 并 不 仅 限 于 象 把 2**10 转 成 1024 这 么 简 单 的 场 合 。 它 还 解析 函 数 调 用 —— 包 括 内 建 的 和 用 户 定 义 的 子 过 程 , 只 要 它 们 符 合 第 六 章 , 子 过 程 , 的 “ 内 联常 量 函 数 ” 的 标 准 。 回 想 一 下 FORTRAN 编 译 器 对 它 们 内 在 函 数 臭 名 昭 著 的 知 识 ,<strong>Perl</strong> 在编 译 的 过 程 中 也 知 道 要 调 用 它 的 哪 些 内 建 函 数 。 这 就 是 为 什 么 如 果 你 试 着 做 log(0.0) 或 者sqrt ( 求 平 方 根 ) 一 个 负 数 的 时 候 , 会 导 致 一 个 编 译 错 误 , 而 不 是 一 个 运 行 时 错 误 , 并 且解 释 器 根 本 没 有 运 行 。( 注 : 实 际 上 , 我 们 在 这 里 实 在 是 简 化 的 太 厉 害 了 。 解 释 器 实 际 上 是运 行 了 , 因 为 那 就 是 常 量 消 除 器 实 现 的 方 法 。 不 过 它 是 在 编 译 时 立 即 运 行 的 , 类 似 BEGIN块 执 行 的 方 式 。)甚 至 任 意 复 杂 的 表 达 式 都 是 提 前 解 析 的 , 有 时 候 导 致 整 个 块 的 删 除 , 象 下 面 这 个 :if (2* sin(1)/cos(1) < 3 && somefn() ) { whatever() }那 些 永 不 计 算 的 东 西 不 会 生 成 任 何 代 码 。 因 为 第 一 部 分 总 是 假 , 所 以 somefn 和whatever 都 不 会 调 用 。( 所 以 不 必 期 待 那 个 语 句 块 里 会 有 goto 标 签 , 因 为 它 甚 至 都 不478

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!