Skip to content

Bad performance of _Reader created by 'then' method #14

@jakublabenski

Description

@jakublabenski

I do not know if this is a bug or correct behaviour. This is what I observed:

from pymonad.reader import Compose

def inc(x: int) -> int:
    print("inc:", x)
    return x + 1

def dec(x: int) -> int:
    print("dec:", x)
    return x - 1

iid = Compose(inc).then(inc).then(dec)
print(iid(0)) 

The result of execution is:

inc: 0
inc: 1
inc: 0
inc: 1
dec: 2
inc: 0
inc: 1
inc: 0
inc: 1
dec: 2
1 

I expected to see this:

inc: 0
inc: 1
dec: 2
1 

Implementation of _bind_or_map is responsible for this:

@pymonad.tools.curry(3)
def _bind_or_map(function_f, function_g, read_only):
    try:
        return _bind(function_f, function_g, read_only)
    except TypeError:
        return _map(function_f, function_g, read_only)

First _bind is used to compute the result. Bind do mapping and fails on actual binding.
Then everything is computed again by _map. This has exponential complexity.

I believe fix could do 'map' then try to 'bind':

@pymonad.tools.curry(3)
def _bind_or_map(function_f, function_g, read_only):
    ret = _map(function_f, function_g, read_only)
    try:
        return ret(read_only)
    except TypeError:
        return ret

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions