URL: https://github.com/freeipa/freeipa/pull/488
Author: tiran
 Title: #488: Speed up client schema cache
Action: opened

PR body:
"""
It's inefficient to open a zip file over and over again. By loading all
members of the schema cache file at once, the ipa CLI script starts
about 25 to 30% faster for simple cases like help and ping.

Before:

```
$ time for i in {1..20}; do ./ipa ping >/dev/null; done

real    0m13.608s
user    0m10.316s
sys     0m1.121s
```

After:

```
$ time for i in {1..20}; do ./ipa ping >/dev/null; done

real    0m9.330s
user    0m7.635s
sys     0m1.146s
```

https://fedorahosted.org/freeipa/ticket/6690

Signed-off-by: Christian Heimes <chei...@redhat.com>
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/488/head:pr488
git checkout pr488
From 26d3b966a9b36f5e0dd9f3a82422249f33f48f6e Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Mon, 20 Feb 2017 20:09:13 +0100
Subject: [PATCH] Speed up client schema cache

It's inefficient to open a zip file over and over again. By loading all
members of the schema cache file at once, the ipa CLI script starts
about 25 to 30% faster for simple cases like help and ping.

Before:

$ time for i in {1..20}; do ./ipa ping >/dev/null; done

real    0m13.608s
user    0m10.316s
sys     0m1.121s

After:

$ time for i in {1..20}; do ./ipa ping >/dev/null; done

real    0m9.330s
user    0m7.635s
sys     0m1.146s

https://fedorahosted.org/freeipa/ticket/6690

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 ipaclient/remote_plugins/schema.py | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
index 15c03f4..13bdee4 100644
--- a/ipaclient/remote_plugins/schema.py
+++ b/ipaclient/remote_plugins/schema.py
@@ -458,11 +458,15 @@ def _read_schema(self, fingerprint):
         with self._open(fingerprint, 'rb') as f:
             self._file.write(f.read())
 
+        # It's more efficient to read zip file members at once than to open
+        # the zip file a couple of times, see #6690.
         with zipfile.ZipFile(self._file, 'r') as schema:
             for name in schema.namelist():
                 ns, _slash, key = name.partition('/')
                 if ns in self.namespaces:
-                    self._dict[ns][key] = None
+                    self._dict[ns][key] = schema.read(name)
+                elif name == '_help':
+                    self._help = schema.read(name)
 
     def __getitem__(self, key):
         try:
@@ -520,16 +524,12 @@ def _write_schema(self, fingerprint):
             f.truncate(0)
             f.write(self._file.read())
 
-    def _read(self, path):
-        with zipfile.ZipFile(self._file, 'r') as zf:
-            return json.loads(zf.read(path).decode('utf-8'))
-
     def read_namespace_member(self, namespace, member):
         value = self._dict[namespace][member]
 
-        if value is None:
-            path = '{}/{}'.format(namespace, member)
-            value = self._dict[namespace][member] = self._read(path)
+        if isinstance(value, bytes):
+            value = json.loads(value.decode('utf-8'))
+            self._dict[namespace][member] = value
 
         return value
 
@@ -537,8 +537,8 @@ def iter_namespace(self, namespace):
         return iter(self._dict[namespace])
 
     def get_help(self, namespace, member):
-        if not self._help:
-            self._help = self._read('_help')
+        if isinstance(self._help, bytes):
+            self._help = json.loads(self._help.decode('utf-8'))
 
         return self._help[namespace][member]
 
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to