Skip to content

Remove usages of cons #5

@chriseidhof

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions