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

Performance of InternedMap #2

Open
torkleyy opened this issue Apr 3, 2018 · 6 comments
Open

Performance of InternedMap #2

torkleyy opened this issue Apr 3, 2018 · 6 comments

Comments

@torkleyy
Copy link
Member

torkleyy commented Apr 3, 2018

While the performance isn't bad, it is "only" about two times faster than FnvHashMap (with strings!).

@OvermindDL1 did you do any benchmarks on your maps? Do you know how they compare to string maps given a size of 32?

@torkleyy
Copy link
Member Author

torkleyy commented Apr 3, 2018

Relevant benchmark:

vnodes/benches/intern.rs

Lines 38 to 49 in 0cc76c1

#[bench]
fn get_interned(b: &mut Bencher) {
let interned = Interned::from("hello");
let mut map = InternedMap::new();
for key in all_keys() {
map.insert(Interned::from(&key as &str), 22);
}
b.iter(|| {
black_box(map.get(black_box(interned)));
});
}

@OvermindDL1
Copy link

I actually didn't benchmark my maps, I mostly just used the unordered_map from Boost up until a few-odd years ago when https://github.com/greg7mdp/sparsepp came out. I only do path lookups rarely, mostly at 'loading' time (like level load or so) and just cached the result where needed in the systems. For dynamic access I'd often use more direct calls as they know what they are accessing anyway so could refine the type to be specific. Mostly at 'play time' the paths would be accessed for debugging information, but otherwise it was almost entirely cached.

Do note, the (hash/tree)maps I generally only used on branching nodes, most specific nodes were a unique type that held it's own information much more specific for it's purpose, like if they were an entity link or a piece of hardware or so.

So honestly I'd not worry too much about performance, it's good to improve it, but it's primarily accessed not at play-time itself so it was never an issue for me.

@torkleyy
Copy link
Member Author

torkleyy commented Apr 3, 2018

I'm pretty sure there will be cases where I don't know the type of the node, but I can cache them, yes.

@OvermindDL1
Copy link

OvermindDL1 commented Apr 3, 2018

Yeah, in my systems I'd often have them be like (not at home so from memory):

struct some_system {
private:
    SomeNode *nodeblah_;
    AnotherNode *nodebloop_;
    Node *unknownnode_;
public:
    some_system(Context &ctx) {
        nodeblah_ = ctx.rootnode<SomeNode>["/dev/some"]; // These are type safe, null pointer if not the right type
        nodebloop_ = ctx.rootnode<AnotherNode>["/vwoop"]["/vweep"];
        unknownnode_ = ctx.rootnode["/some/node/that/I/don't/know/the/type/of"];
        assert(nodeblah_);
        assert(nodebloop_);
        assert(unknownnode_);
    }

    void operator()() {
        // process system, maybe access `nodeblah_` straight, maybe access a
        // child of nodebloop_, maybe set event hooks on unknownnode_, whatever...
    }

    // ... other things  It was templated so only relevant parts were accessed
    // efficiently without pointer indirections needed as well as being able to
    // generate 'most' of the dependency graph at compile-time and generated the
    // rest at load-time.
}

@torkleyy
Copy link
Member Author

torkleyy commented Apr 3, 2018 via email

@OvermindDL1
Copy link

OvermindDL1 commented Apr 3, 2018

The problem I see with hardcoding the type is that the node cannot be
easily overwritten, which could be quite useful for modding.

Hmm, I've never actually needed to script-up a node that wasn't an entity so I've never seen the need. Most of my 'nodes' are just entity link's (EntityNode), which you then pass to systems as normal. Systems, on the other hand, have been heavily scripted and modded (as well as components). Scripts/mods can, however, 'access' Nodes with no issues, including via their fully dynamic interfaces.

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

2 participants