switch to Google's (C++) Protobuf implementation

Brings the 100 field test down from 3 secs to 0.15 secs.

"betterproto" indeed!
This commit is contained in:
Damien Elmes 2019-12-24 14:48:49 +10:00
parent 3ce4d5fd3d
commit b54c127372
4 changed files with 15 additions and 14 deletions

2
.gitignore vendored
View file

@ -10,7 +10,7 @@
.pytype .pytype
__pycache__ __pycache__
anki/buildhash.py anki/buildhash.py
anki/proto anki/bridge_pb2.py
aqt/forms aqt/forms
locale locale
rs/ankirs/src/proto.rs rs/ankirs/src/proto.rs

View file

@ -130,7 +130,7 @@ BUILDDEPS := .build/ui .build/js .build/rs .build/py-proto
@touch $@ @touch $@
.build/py-proto: $(RUNREQS) $(PROTODEPS) .build/py-proto: $(RUNREQS) $(PROTODEPS)
protoc -I proto --python_betterproto_out=anki/proto proto/bridge.proto protoc --proto_path=proto --python_out=anki proto/bridge.proto
@touch $@ @touch $@
.PHONY: build clean .PHONY: build clean

View file

@ -1,9 +1,8 @@
from typing import Dict, List from typing import Dict, List
import _ankirs # pytype: disable=import-error import _ankirs # pytype: disable=import-error
import betterproto
from anki.proto import proto as pb import anki.bridge_pb2 as pb
from .types import AllTemplateReqs from .types import AllTemplateReqs
@ -11,13 +10,13 @@ from .types import AllTemplateReqs
class BridgeException(Exception): class BridgeException(Exception):
def __str__(self) -> str: def __str__(self) -> str:
err: pb.BridgeError = self.args[0] # pylint: disable=unsubscriptable-object err: pb.BridgeError = self.args[0] # pylint: disable=unsubscriptable-object
(kind, obj) = betterproto.which_one_of(err, "value") kind = err.WhichOneof("value")
if kind == "invalid_input": if kind == "invalid_input":
return f"invalid input: {obj.info}" return f"invalid input: {err.invalid_input.info}"
elif kind == "template_parse": elif kind == "template_parse":
return f"template parse: {obj.info}" return f"template parse: {err.template_parse.info}"
else: else:
return f"unhandled error: {err} {obj}" return f"unhandled error: {err}"
def proto_template_reqs_to_legacy( def proto_template_reqs_to_legacy(
@ -25,7 +24,7 @@ def proto_template_reqs_to_legacy(
) -> AllTemplateReqs: ) -> AllTemplateReqs:
legacy_reqs = [] legacy_reqs = []
for (idx, req) in enumerate(reqs): for (idx, req) in enumerate(reqs):
(kind, val) = betterproto.which_one_of(req, "value") kind = req.WhichOneof("value")
# fixme: sorting is for the unit tests - should check if any # fixme: sorting is for the unit tests - should check if any
# code depends on the order # code depends on the order
if kind == "any": if kind == "any":
@ -43,12 +42,13 @@ class RSBridge:
self._bridge = _ankirs.Bridge() self._bridge = _ankirs.Bridge()
def _run_command(self, input: pb.BridgeInput) -> pb.BridgeOutput: def _run_command(self, input: pb.BridgeInput) -> pb.BridgeOutput:
input_bytes = bytes(input) input_bytes = input.SerializeToString()
output_bytes = self._bridge.command(input_bytes) output_bytes = self._bridge.command(input_bytes)
output = pb.BridgeOutput().parse(output_bytes) output = pb.BridgeOutput()
(kind, obj) = betterproto.which_one_of(output, "value") output.ParseFromString(output_bytes)
kind = output.WhichOneof("value")
if kind == "error": if kind == "error":
raise BridgeException(obj) raise BridgeException(output.error)
else: else:
return output return output

View file

@ -8,4 +8,5 @@ jsonschema
psutil; sys_platform == "win32" psutil; sys_platform == "win32"
distro; sys_platform != "win32" and sys_platform != "darwin" distro; sys_platform != "win32" and sys_platform != "darwin"
typing typing
betterproto[compiler] protobuf