Skip to content

Where to look for potential JSON parser improvements #17

@turanct

Description

@turanct

1. whitespace parser

zeroOrMore(satisfy(isCharCode([0x20, 0x0A, 0x0D, 0x09])))

it's potentially faster to do takeWhile on the stream, with the same predicate, skipping the zeroOrMore combinator and the satisfy.

https://github.com/mathiasverraes/parsica/blob/main/src/JSON/JSON.php#L154-L158

2. between

we rely heavily on between, which is based on sequence and bind. If we would find the tiniest speed improvement in those, we would make the parser a lot faster.

https://github.com/mathiasverraes/parsica/blob/main/src/JSON/JSON.php#L96-L103

3. sepby

we rely on this function often in the JSON parser too. It is built in terms of sepBy1 which is written in a "readable" way, but not a really efficient way:

function sepBy1(Parser $separator, Parser $parser): Parser
{
    $prepend = fn($x) => fn(array $xs): array => array_merge([$x], $xs);
    $label = $parser->getLabel() . ", separated by " . $separator->getLabel();
    return pure($prepend)->apply($parser)->apply(many($separator->sequence($parser)))->label($label);
}
  • The prepend uses array_merge to prepend a single element, could probably be faster with array_unshift
  • although the applicative is really readable here, it's also a complex operation under the hood, and like the sequence and bind the tiniest improvement here would probably make a big difference

https://github.com/mathiasverraes/parsica/blob/main/src/JSON/JSON.php#L99-L102
https://github.com/mathiasverraes/parsica/blob/main/src/combinators.php#L513-L519

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