Added support for query preparation to the Subprocess algorithm wrapper
Algorithms run in subprocesses need to do a lot of serialising and
unserialising of query points; cutting that overhead out should give a more
realistic view of their actual performance
@@ -30,22 +30,36 @@ class Subprocess(BaseANN):
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
universal_newlines = True)
+
for key, value in self._params.iteritems():
self.__write("%s %s" % \
(Subprocess.__quote(key), Subprocess.__quote(value)))
assert self.__line()[0] == "ok", """\
assigning value '%s' to option '%s' failed""" % (value, key)
+ if self._prepared:
+ self.__write("frontend prepared-queries 1")
+ assert self.__line()[0] == "ok", """\
+enabling prepared queries mode failed"""
+
self.__write("")
assert self.__line()[0] == "ok", """\
transitioning to training mode failed"""
return self._program
- def __init__(self, args, encoder, params):
+ def __init__(self, args, encoder, params, prepared = False):
self.name = "Subprocess(program = %s, %s)" % (args[0], str(params))
self._program = None
self._args = args
self._encoder = encoder
self._params = params
+ self._prepared = prepared
+ if not prepared:
+ self.query = self.__query_normal
+ else:
+ self.query = self.__query_prepared
+
+ def supports_prepared_queries(self):
+ return self._prepared
def fit(self, X):
for entry in X:
@@ -57,9 +71,16 @@ encoded training point '%s' was rejected""" % d
assert self.__line()[0] == "ok", """\
transitioning to query mode failed"""
- def query(self, v, n):
+ def __query_normal(self, v, n):
d = Subprocess.__quote(self._encoder(v))
self.__write("%s %d" % (d, n))
+ return self.__handle_query_response()
+
+ def __query_prepared(self, v, n):
+ self.prepare_query(v, n)
+ return self.run_prepared_query()
+
+ def __handle_query_response(self):
status = self.__line()
if status[0] == "ok":
count = int(status[1])
@@ -76,6 +97,16 @@ transitioning to query mode failed"""
searching for encoded query point '%s' neither succeeded nor failed""" % d
return []
+ def prepare_query(self, v, n):
+ d = Subprocess.__quote(self._encoder(v))
+ self.__write("%s %d" % (d, n))
+ assert self.__line()[0] == "ok", """\
+preparing the query '%s' failed""" % d
+
+ def run_prepared_query(self):
+ self.__write("query")
+ return self.__handle_query_response()
+
def use_threads(self):
return False
def done(self):
