Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-implement selectors as filters #343

Open
smallnamespace opened this issue Apr 23, 2016 · 7 comments
Open

Re-implement selectors as filters #343

smallnamespace opened this issue Apr 23, 2016 · 7 comments
Assignees

Comments

@smallnamespace
Copy link
Collaborator

smallnamespace commented Apr 23, 2016

@djkaty @jleclanche

While we're on the topic of selector optimizations, right now the reason the selectors build up lists of entities and tear them down again is because while most selectors are just simple filters on entities, there are some that aren't, such as FuncSelector and RandomSelector.

This sucks, because what I'd like to do is simply (pseudo-code follows):

class Selector:
  __init__(self, filter: Callable[Entity, Entity, bool])
    self.filter = filter

  def evaluate(self, source, entities):
    return [e for e in entities if self.filter(source, e)]

and so set operations are basically free:

class AndSelector:
  __init__(self, left, right)
    self.filter = lambda s, e: left.filter(s, e) and right.filter(s, e)

No intermediate lists at all. As a first guess, this will lead to at least a 2-3x speedup, because selectors like FRIENDLY_MINIONS do at least 2x the work.

This will require changing the DSL a bit though -- thoughts?

@jleclanche
Copy link
Owner

I'm good with a reimplementation to turn them into filters. The hard part is implementing selector operations (adding/removing selectors, etc).

As a sidenote, I may have mentioned this before, I've been thinking about a way to hijack random selectors in order to force a random outcome to select something specific. eg. hijack(RANDOM_ENEMY_CHARACTER, ENEMY_HERO) would replace one selector with another. This would be immensely useful for forcing rng test outcomes without preseeding and it'd be good if a rewrite keeps this in mind.

@smallnamespace
Copy link
Collaborator Author

Sounds good, I'll take a stab at doing this.

hijack sounds tricky to implement in a safely overridable way (if we wanted hijack(RANDOM_ENEMY_CHARACTER, SELF) to fail), but otherwise it doesn't seem too problematic.

@jleclanche
Copy link
Owner

We wouldn't want it to fail.

@smallnamespace
Copy link
Collaborator Author

But then you won't catch improper use of hijack. Shouldn't be a problem I guess, if it's just for testing.

@jleclanche
Copy link
Owner

Yeah that's completely fine.

@djkaty
Copy link
Collaborator

djkaty commented May 6, 2016

I'm going to test it but those set operations will be far from free. A 3-way And requires 5 function calls per tested entity.

@djkaty
Copy link
Collaborator

djkaty commented May 8, 2016

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

No branches or pull requests

3 participants