It’s good practice to design APIs to make race conditions less likely, by explicitly not splitting operations across multiple calls.
Separating “exists” and “get” into separate calls is a disaster.
I guess databases and file systems are different because concurrent access is the norm, not the exception, and APIs should be designed accordingly. But for most of your in-memory structures, you probably don't want them dealing with concurrency because they aren't going to be able do that very well anyways (instead, deal with concurrency outside of the data structure and have them throw when inconsistencies from bad concurrency policies arise).
(Okay, probably not twice as slow, since the cache will be hot, but still.)
Or if you "know" it's there call the version that throws an exception if it isn't.