Verified Commit d80c4c30 authored by Yorick Peterse's avatar Yorick Peterse 🌴

Use BufReader when reading bytecode from files

Using a 32KB buffer this allows us to drastically reduce the time spent
parsing bytecode files. Consider the following program:

    import std::ansi
    import std::ffi
    import std::fs
    import std::mirror
    import std::stdio::stderr
    import std::stdio::stdin
    import std::stdio::stdout
    import std::time

    stdout.print('hello world')

Prior to these changes, running this program (ignoring the compilation
itme) takes around 240 milliseconds. With these changes, this is reduced
to 20 milliseconds: a 12x improvement.
parent 47580733
Pipeline #41499152 passed with stages
in 19 minutes and 41 seconds
...@@ -12,17 +12,16 @@ ...@@ -12,17 +12,16 @@
//! //!
//! let result = bytecode_parser::parse_file("path/to/file.inkoc"); //! let result = bytecode_parser::parse_file("path/to/file.inkoc");
use catch_table::{CatchEntry, CatchTable};
use compiled_code::CompiledCode;
use num_bigint::BigInt; use num_bigint::BigInt;
use object_pointer::ObjectPointer;
use std::f64; use std::f64;
use std::fs::File; use std::fs::File;
use std::io::prelude::*; use std::io::prelude::*;
use std::io::Bytes; use std::io::{BufReader, Bytes};
use std::mem; use std::mem;
use std::str; use std::str;
use catch_table::{CatchEntry, CatchTable};
use compiled_code::CompiledCode;
use object_pointer::ObjectPointer;
use vm::instruction::{Instruction, InstructionType}; use vm::instruction::{Instruction, InstructionType};
use vm::state::RcState; use vm::state::RcState;
...@@ -89,6 +88,9 @@ const OBJECT_LITERALS_LIMIT: u64 = ...@@ -89,6 +88,9 @@ const OBJECT_LITERALS_LIMIT: u64 =
const CATCH_ENTRIES_LIMIT: u64 = const CATCH_ENTRIES_LIMIT: u64 =
VECTOR_LITERAL_SIZE_LIMIT / mem::size_of::<CatchEntry>() as u64; VECTOR_LITERAL_SIZE_LIMIT / mem::size_of::<CatchEntry>() as u64;
/// The number of bytes to buffer for every read from a bytecode file.
const BUFFER_SIZE: usize = 32 * 1024;
#[derive(Debug)] #[derive(Debug)]
pub enum ParserError { pub enum ParserError {
InvalidFile, InvalidFile,
...@@ -117,7 +119,10 @@ pub type BytecodeResult = ParserResult<CompiledCode>; ...@@ -117,7 +119,10 @@ pub type BytecodeResult = ParserResult<CompiledCode>;
/// let result = bytecode_parser::parse_file(&state, "path/to/file.inkoc"); /// let result = bytecode_parser::parse_file(&state, "path/to/file.inkoc");
pub fn parse_file(state: &RcState, path: &str) -> BytecodeResult { pub fn parse_file(state: &RcState, path: &str) -> BytecodeResult {
match File::open(path) { match File::open(path) {
Ok(file) => parse(state, &mut file.bytes()), Ok(file) => parse(
state,
&mut BufReader::with_capacity(BUFFER_SIZE, file).bytes(),
),
Err(_) => parser_error!(InvalidFile), Err(_) => parser_error!(InvalidFile),
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment