Attribute access for partially split objects#27
Conversation
| thing3=(int, 2, {"byteorder": "big"}) | ||
| ) | ||
| def sip(self): | ||
| return "Mmmm" |
There was a problem hiding this comment.
ELAINE: Yeah, in college I sat next to an Alex in art history. And he was always drinking coffee and after every sip he would go: "Ahh!". I mean every two seconds: "Ahh!". And he would take like 40 sips and after everyone: "Ahh!". I had to drop the class.
| self._finished_values[message_name] = produce_value(message_class, | ||
| message_name, | ||
| bytes_for_message, | ||
| kwargs) |
There was a problem hiding this comment.
An extremely minor comment: My obsessive-compulsive self tells me that both calls to produce_value() (here and L53) have the arguments not well aligned.
| bytes_for_message, | ||
| kwargs) | ||
| produced_value = produce_value(message_class, message_name, bytes_for_message, kwargs) | ||
| del self.processed_objects[message_name] # We don't do this as a pop() in case produce_value raises. |
There was a problem hiding this comment.
I don't understand this comment, can you elaborate?
There was a problem hiding this comment.
It'd be marginally more optimal to do self.processed_objects.pop(message_name), but in the (rare, but not unsupported) case that something changes in the receiver class such that produce_value raises at this time (but is caught and subsequently proceeds successfully), we'd already have erased it from processed_objects.
| try: | ||
| return self._finished_values[message_name] | ||
| except KeyError: # suppress might be good here, but it appears to have a performance penalty, and this is a performance-concerned function. | ||
| pass |
There was a problem hiding this comment.
Heh - interesting - does .get share a similar performance hit?
There was a problem hiding this comment.
.get has what appears to be a measurable, but substantially smaller performance hit. Here's what I said in Discord about it:
Interesting: I just ran three test scenarios on the "just in time attribute access", each access an attribute 500000 times from a partially split bytestring.
It's possible that the value has been "finished" (ie, passed to its receiver), so we have to both check that and return the finished value, and then finish the value if it hasn't previously been.
They are both dicts.
I tried with .get(...), with a try block (and except: pass), and suppress.
The times were more different than I thought:
The try block was about 4.2 seconds, the .get was about 4.6 seconds, and the suppress was 6.2 seconds (!).
At some point, we can do some more formal benchmarking. It doesn't feel like the best use of my time right now.
vepkenez
left a comment
There was a problem hiding this comment.
I like it. Why are we doing this now? Where is this needed?
|
@vepkenez - It is needed in nucypher in order to read the |
|
@vepkenez: It's also something like 15% more optimal on its own (though I'm not doing bechmarking right now except with very quick local |
Fixes #26