Skip to content

Remove usages of cons #5

Description

@chriseidhof

When we use a lot of cons (e.g. in many) this will slow down the code, because a copy of the array has to be made and inserting at index 0 is O(n).

There are a couple of workarounds. The most "brute-force" one would be to rewrite many (and other combinators). I'm sorry, the code is quite ugly, but I think many parts can be factored out nicely to keep everything in a functional style. The key trick is to have one result array that's not shared, so the compiler can modify it without making copies.

public func many<In, Out, Outs: RangeReplaceableCollectionType where Outs.Generator.Element == Out>(p: Parser<In, Out>) -> Parser<In, Outs>
{
    return Parser { input in
        var result = Outs()
        var remainder = input
        while true {
            switch parse(p, remainder) {
            case .Done(let input, let out):
                result.append(out)
                remainder = input
            case .Fail(_, _, _): return .Done(remainder, result)
            }
        }
    }
}

This makes it twice as fast on my machine! I think some other cases are manyTill, sepBy1, count, etc.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions