From dfd60426d8da06c817c6d3f71901b4f1c013a819 Mon Sep 17 00:00:00 2001
From: mathieui <mathieui@mathieui.net>
Date: Fri, 8 May 2015 20:37:21 +0200
Subject: Micro-optimizations on refresh
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Reduce the number of calls to config.get whenever possible. Yields a
performance improvement of at least 10% for the basic use case of
"receiving a message in the current tab". Logging stuff isn’t free
either, even when the call should be a no-op, so we should try to make
the debug log less verbose.
---
 src/events.py             |  5 -----
 src/windows/funcs.py      |  4 +---
 src/windows/info_bar.py   |  7 ++++---
 src/windows/muc.py        |  9 +++++----
 src/windows/roster_win.py | 19 ++++++++++++-------
 src/windows/text_win.py   | 35 +++++++++++++++++++----------------
 6 files changed, 41 insertions(+), 38 deletions(-)

(limited to 'src')

diff --git a/src/events.py b/src/events.py
index 50711022..15ef3e35 100644
--- a/src/events.py
+++ b/src/events.py
@@ -10,9 +10,6 @@ The list of available events is here:
 http://poezio.eu/doc/en/plugins.html#_poezio_events
 """
 
-import logging
-log = logging.getLogger(__name__)
-
 class EventHandler(object):
     """
     A class keeping a list of possible events that are triggered
@@ -71,9 +68,7 @@ class EventHandler(object):
         """
         callbacks = self.events.get(name, None)
         if callbacks is None:
-            log.debug('%s: No such event.', name)
             return
-        log.debug('Event %s triggered, callbacks: %s', name, callbacks)
         for callback in callbacks:
             callback(*args, **kwargs)
 
diff --git a/src/windows/funcs.py b/src/windows/funcs.py
index d58d4683..f1401628 100644
--- a/src/windows/funcs.py
+++ b/src/windows/funcs.py
@@ -4,7 +4,6 @@ Standalone functions used by the modules
 
 import string
 
-from config import config
 from . base_wins import FORMAT_CHAR, format_chars
 
 def find_first_format_char(text, chars=None):
@@ -19,8 +18,7 @@ def find_first_format_char(text, chars=None):
             pos = p
     return pos
 
-def truncate_nick(nick, size=None):
-    size = size or config.get('max_nick_length')
+def truncate_nick(nick, size=10):
     if size < 1:
         size = 1
     if nick and len(nick) > size:
diff --git a/src/windows/info_bar.py b/src/windows/info_bar.py
index e66343c5..abd956cd 100644
--- a/src/windows/info_bar.py
+++ b/src/windows/info_bar.py
@@ -28,6 +28,7 @@ class GlobalInfoBar(Win):
         show_names = config.get('show_tab_names')
         show_nums = config.get('show_tab_numbers')
         use_nicks = config.get('use_tab_nicks')
+        show_inactive = config.get('show_inactive_tabs')
         # ignore any remaining gap tabs if the feature is not enabled
         if create_gaps:
             sorted_tabs = self.core.tabs[:]
@@ -37,8 +38,7 @@ class GlobalInfoBar(Win):
         for nb, tab in enumerate(sorted_tabs):
             if not tab: continue
             color = tab.color
-            if not config.get('show_inactive_tabs') and\
-                    color is get_theme().COLOR_TAB_NORMAL:
+            if not show_inactive and color is get_theme().COLOR_TAB_NORMAL:
                 continue
             try:
                 if show_nums or not show_names:
@@ -87,9 +87,10 @@ class VerticalGlobalInfoBar(Win):
                 sorted_tabs = sorted_tabs[-height:]
             else:
                 sorted_tabs = sorted_tabs[pos-height//2 : pos+height//2]
+        asc_sort = (config.get('vertical_tab_list_sort') == 'asc')
         for y, tab in enumerate(sorted_tabs):
             color = tab.vertical_color
-            if not config.get('vertical_tab_list_sort') != 'asc':
+            if asc_sort:
                 y = height - y - 1
             self.addstr(y, 0, "%2d" % tab.nb,
                     to_curses_attr(get_theme().COLOR_VERTICAL_TAB_NUMBER))
diff --git a/src/windows/muc.py b/src/windows/muc.py
index 7e3541ba..c4e8df6e 100644
--- a/src/windows/muc.py
+++ b/src/windows/muc.py
@@ -37,7 +37,8 @@ class UserList(Win):
         if config.get('hide_user_list'):
             return # do not refresh if this win is hidden.
         self._win.erase()
-        if config.get('user_list_sort').lower() == 'asc':
+        asc_sort = (config.get('user_list_sort').lower() == 'asc')
+        if asc_sort:
             y, x = self._win.getmaxyx()
             y -= 1
             users = sorted(users)
@@ -55,7 +56,7 @@ class UserList(Win):
             self.addstr(y, 2,
                     poopt.cut_by_columns(user.nick, self.width - 2),
                     to_curses_attr(user.color))
-            if config.get('user_list_sort').lower() == 'asc':
+            if asc_sort:
                 y -= 1
             else:
                 y += 1
@@ -63,12 +64,12 @@ class UserList(Win):
                 break
         # draw indicators of position in the list
         if self.pos > 0:
-            if config.get('user_list_sort').lower() == 'asc':
+            if asc_sort:
                 self.draw_plus(self.height-1)
             else:
                 self.draw_plus(0)
         if self.pos + self.height < len(users):
-            if config.get('user_list_sort').lower() == 'asc':
+            if asc_sort:
                 self.draw_plus(0)
             else:
                 self.draw_plus(self.height-1)
diff --git a/src/windows/roster_win.py b/src/windows/roster_win.py
index 6ecb6128..a2e2badd 100644
--- a/src/windows/roster_win.py
+++ b/src/windows/roster_win.py
@@ -145,6 +145,12 @@ class RosterWin(Win):
         # draw the roster from the cache
         roster_view = self.roster_cache[self.start_pos-1:self.start_pos+self.height]
 
+        options = {
+            'show_roster_sub': config.get('show_roster_subscriptions'),
+            'show_s2s_errors': config.get('show_s2s_errors'),
+            'show_roster_jids': config.get('show_roster_jids')
+        }
+
         for item in roster_view:
             draw_selected = False
             if y -2 + self.start_pos == self.pos:
@@ -155,7 +161,7 @@ class RosterWin(Win):
                 self.draw_group(y, item, draw_selected)
                 group = item.name
             elif isinstance(item, Contact):
-                self.draw_contact_line(y, item, draw_selected, group)
+                self.draw_contact_line(y, item, draw_selected, group, **options)
             elif isinstance(item, Resource):
                 self.draw_resource_line(y, item, draw_selected)
 
@@ -206,7 +212,8 @@ class RosterWin(Win):
             return name
         return name[:self.width - added - 1] + '…'
 
-    def draw_contact_line(self, y, contact, colored, group):
+    def draw_contact_line(self, y, contact, colored, group, show_roster_sub=False,
+                          show_s2s_errors=True, show_roster_jids=False):
         """
         Draw on a line all informations about one contact.
         This is basically the highest priority resource's informations
@@ -229,15 +236,13 @@ class RosterWin(Win):
         self.addstr(y, 0, ' ')
         self.addstr(theme.CHAR_STATUS, to_curses_attr(color))
 
-        show_roster_sub = config.get('show_roster_subscriptions')
-
         self.addstr(' ')
         if resource:
             self.addstr('[+] ' if contact.folded(group) else '[-] ')
             added += 4
         if contact.ask:
             added += len(get_theme().CHAR_ROSTER_ASKED)
-        if config.get('show_s2s_errors') and contact.error:
+        if show_s2s_errors and contact.error:
             added += len(get_theme().CHAR_ROSTER_ERROR)
         if contact.tune:
             added += len(get_theme().CHAR_ROSTER_TUNE)
@@ -250,7 +255,7 @@ class RosterWin(Win):
         if show_roster_sub in ('all', 'incomplete', 'to', 'from', 'both', 'none'):
             added += len(theme.char_subscription(contact.subscription, keep=show_roster_sub))
 
-        if not config.get('show_roster_jids') and contact.name:
+        if not show_roster_jids and contact.name:
             display_name = '%s' % contact.name
         elif contact.name and contact.name != contact.bare_jid:
             display_name = '%s (%s)' % (contact.name, contact.bare_jid)
@@ -268,7 +273,7 @@ class RosterWin(Win):
             self.addstr(theme.char_subscription(contact.subscription, keep=show_roster_sub), to_curses_attr(theme.COLOR_ROSTER_SUBSCRIPTION))
         if contact.ask:
             self.addstr(get_theme().CHAR_ROSTER_ASKED, to_curses_attr(get_theme().COLOR_IMPORTANT_TEXT))
-        if config.get('show_s2s_errors') and contact.error:
+        if show_s2s_errors and contact.error:
             self.addstr(get_theme().CHAR_ROSTER_ERROR, to_curses_attr(get_theme().COLOR_ROSTER_ERROR))
         if contact.tune:
             self.addstr(get_theme().CHAR_ROSTER_TUNE, to_curses_attr(get_theme().COLOR_ROSTER_TUNE))
diff --git a/src/windows/text_win.py b/src/windows/text_win.py
index bdda721c..59c5230b 100644
--- a/src/windows/text_win.py
+++ b/src/windows/text_win.py
@@ -63,13 +63,13 @@ class BaseTextWin(Win):
             self.pos = 0
         return self.pos != pos
 
-    def build_new_message(self, message, history=None, clean=True, highlight=False, timestamp=False):
+    def build_new_message(self, message, history=None, clean=True, highlight=False, timestamp=False, nick_size=10):
         """
         Take one message, build it and add it to the list
         Return the number of lines that are built for the given
         message.
         """
-        lines = self.build_message(message, timestamp=timestamp)
+        lines = self.build_message(message, timestamp=timestamp, nick_size=nick_size)
         if self.lock:
             self.lock_buffer.extend(lines)
         else:
@@ -81,7 +81,7 @@ class BaseTextWin(Win):
                 self.built_lines.pop(0)
         return len(lines)
 
-    def build_message(self, message, timestamp=False):
+    def build_message(self, message, timestamp=False, nick_size=10):
         """
         Build a list of lines from a message, without adding it
         to a list
@@ -125,8 +125,9 @@ class BaseTextWin(Win):
     def rebuild_everything(self, room):
         self.built_lines = []
         with_timestamps = config.get('show_timestamps')
+        nick_size = config.get('max_nick_length')
         for message in room.messages:
-            self.build_new_message(message, clean=False, timestamp=with_timestamps)
+            self.build_new_message(message, clean=False, timestamp=with_timestamps, nick_size=nick_size)
             if self.separator_after is message:
                 self.build_new_message(None)
         while len(self.built_lines) > self.lines_nb_limit:
@@ -265,13 +266,13 @@ class TextWin(BaseTextWin):
             if room and room.messages:
                 self.separator_after = room.messages[-1]
 
-    def build_new_message(self, message, history=None, clean=True, highlight=False, timestamp=False):
+    def build_new_message(self, message, history=None, clean=True, highlight=False, timestamp=False, nick_size=10):
         """
         Take one message, build it and add it to the list
         Return the number of lines that are built for the given
         message.
         """
-        lines = self.build_message(message, timestamp=timestamp)
+        lines = self.build_message(message, timestamp=timestamp, nick_size=nick_size)
         if self.lock:
             self.lock_buffer.extend(lines)
         else:
@@ -288,7 +289,7 @@ class TextWin(BaseTextWin):
                 self.built_lines.pop(0)
         return len(lines)
 
-    def build_message(self, message, timestamp=False):
+    def build_message(self, message, timestamp=False, nick_size=10):
         """
         Build a list of lines from a message, without adding it
         to a list
@@ -304,7 +305,7 @@ class TextWin(BaseTextWin):
         else:
             default_color = None
         ret = []
-        nick = truncate_nick(message.nickname)
+        nick = truncate_nick(message.nickname, nick_size)
         offset = 0
         if message.ack:
             if message.ack > 0:
@@ -349,12 +350,14 @@ class TextWin(BaseTextWin):
         else:
             lines = self.built_lines[-self.height-self.pos:-self.pos]
         with_timestamps = config.get("show_timestamps")
+        nick_size = config.get("max_nick_length")
         self._win.move(0, 0)
         self._win.erase()
         for y, line in enumerate(lines):
             if line:
                 msg = line.msg
                 if line.start_pos == 0:
+                    nick = truncate_nick(msg.nickname, nick_size)
                     if msg.nick_color:
                         color = msg.nick_color
                     elif msg.user:
@@ -371,14 +374,14 @@ class TextWin(BaseTextWin):
                     if msg.me:
                         self._win.attron(to_curses_attr(get_theme().COLOR_ME_MESSAGE))
                         self.addstr('* ')
-                        self.write_nickname(msg.nickname, color, msg.highlight)
+                        self.write_nickname(nick, color, msg.highlight)
                         if msg.revisions:
                             self._win.attron(to_curses_attr(get_theme().COLOR_REVISIONS_MESSAGE))
                             self.addstr('%d' % msg.revisions)
                             self._win.attrset(0)
                         self.addstr(' ')
                     else:
-                        self.write_nickname(msg.nickname, color, msg.highlight)
+                        self.write_nickname(nick, color, msg.highlight)
                         if msg.revisions:
                             self._win.attron(to_curses_attr(get_theme().COLOR_REVISIONS_MESSAGE))
                             self.addstr('%d' % msg.revisions)
@@ -401,8 +404,7 @@ class TextWin(BaseTextWin):
                 # Offset for the nickname (if any)
                 # plus a space and a > after it
                 if line.msg.nickname:
-                    offset += poopt.wcswidth(
-                                truncate_nick(line.msg.nickname))
+                    offset += poopt.wcswidth(truncate_nick(line.msg.nickname, nick_size))
                     if line.msg.me:
                         offset += 3
                     else:
@@ -459,7 +461,7 @@ class TextWin(BaseTextWin):
                 color = hl_color
         if color:
             self._win.attron(to_curses_attr(color))
-        self.addstr(truncate_nick(nickname))
+        self.addstr(nickname)
         if color:
             self._win.attroff(to_curses_attr(color))
         if highlight and hl_color == "reverse":
@@ -471,6 +473,7 @@ class TextWin(BaseTextWin):
         (instead of rebuilding everything in order to correct a message)
         """
         with_timestamps = config.get('show_timestamps')
+        nick_size = config.get('max_nick_length')
         for i in range(len(self.built_lines)-1, -1, -1):
             if self.built_lines[i] and self.built_lines[i].msg.identifier == old_id:
                 index = i
@@ -478,7 +481,7 @@ class TextWin(BaseTextWin):
                     self.built_lines.pop(index)
                     index -= 1
                 index += 1
-                lines = self.build_message(message, timestamp=with_timestamps)
+                lines = self.build_message(message, timestamp=with_timestamps, nick_size=nick_size)
                 for line in lines:
                     self.built_lines.insert(index, line)
                     index += 1
@@ -536,11 +539,11 @@ class XMLTextWin(BaseTextWin):
         self._win.attrset(0)
         self._refresh()
 
-    def build_message(self, message, timestamp=False):
+    def build_message(self, message, timestamp=False, nick_size=10):
         txt = message.txt
         ret = []
         default_color = None
-        nick = truncate_nick(message.nickname)
+        nick = truncate_nick(message.nickname, nick_size)
         offset = 0
         if nick:
             offset += poopt.wcswidth(nick) + 1 # + nick + ' ' length
-- 
cgit v1.2.3