diff options
author | Florian Bruhin <me@the-compiler.org> | 2019-07-04 10:28:26 +0200 |
---|---|---|
committer | Florian Bruhin <me@the-compiler.org> | 2019-07-04 10:28:26 +0200 |
commit | 6ba6314f716ac8d35116b93a16139fadda627c30 (patch) | |
tree | 4b4fd4dda863b6a106c243182dee71a94cde28cb | |
parent | 70d27ce7fd644e8588fb481ff62798024d888ad1 (diff) | |
parent | 564a69e507c5c0cf54f34fe1dd1cf0fd7880f181 (diff) | |
download | qutebrowser-6ba6314f716ac8d35116b93a16139fadda627c30.tar.gz qutebrowser-6ba6314f716ac8d35116b93a16139fadda627c30.zip |
Merge remote-tracking branch 'origin/pr/4819'
-rw-r--r-- | qutebrowser/browser/webkit/webkithistory.py | 2 | ||||
-rw-r--r-- | qutebrowser/config/config.py | 3 | ||||
-rw-r--r-- | qutebrowser/config/configdata.py | 2 | ||||
-rw-r--r-- | qutebrowser/config/configtypes.py | 3 | ||||
-rw-r--r-- | qutebrowser/mainwindow/tabwidget.py | 3 | ||||
-rw-r--r-- | qutebrowser/misc/debugcachestats.py | 49 | ||||
-rw-r--r-- | qutebrowser/misc/utilcmds.py | 33 | ||||
-rw-r--r-- | scripts/dev/check_coverage.py | 1 |
8 files changed, 62 insertions, 34 deletions
diff --git a/qutebrowser/browser/webkit/webkithistory.py b/qutebrowser/browser/webkit/webkithistory.py index a0d41088d..aafa45f9a 100644 --- a/qutebrowser/browser/webkit/webkithistory.py +++ b/qutebrowser/browser/webkit/webkithistory.py @@ -24,6 +24,7 @@ import functools from PyQt5.QtWebKit import QWebHistoryInterface from qutebrowser.utils import debug +from qutebrowser.misc import debugcachestats class WebHistoryInterface(QWebHistoryInterface): @@ -42,6 +43,7 @@ class WebHistoryInterface(QWebHistoryInterface): def addHistoryEntry(self, url_string): """Required for a QWebHistoryInterface impl, obsoleted by add_url.""" + @debugcachestats.register(name='history') @functools.lru_cache(maxsize=32768) def historyContains(self, url_string): """Called by WebKit to determine if a URL is contained in the history. diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py index a51126c1b..4eb6f2a1f 100644 --- a/qutebrowser/config/config.py +++ b/qutebrowser/config/config.py @@ -29,7 +29,7 @@ from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl from qutebrowser.config import configdata, configexc, configutils from qutebrowser.utils import utils, log, jinja, urlmatch -from qutebrowser.misc import objects +from qutebrowser.misc import objects, debugcachestats from qutebrowser.keyinput import keyutils MYPY = False @@ -625,6 +625,7 @@ def set_register_stylesheet(obj: QObject, *, observer.register() +@debugcachestats.register() @functools.lru_cache() def _render_stylesheet(stylesheet: str) -> str: """Render the given stylesheet jinja template.""" diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 71ce74a47..b500fcb2e 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -31,6 +31,7 @@ import functools import attr from qutebrowser.config import configtypes from qutebrowser.utils import usertypes, qtutils, utils +from qutebrowser.misc import debugcachestats DATA = typing.cast(typing.Mapping[str, 'Option'], None) MIGRATIONS = typing.cast('Migrations', None) @@ -267,6 +268,7 @@ def _read_yaml( return parsed, migrations +@debugcachestats.register() @functools.lru_cache(maxsize=256) def is_valid_prefix(prefix: str) -> bool: """Check whether the given prefix is a valid prefix for some option.""" diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 0cb51f756..e43871ca6 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -60,7 +60,7 @@ from PyQt5.QtGui import QColor, QFont from PyQt5.QtWidgets import QTabWidget, QTabBar from PyQt5.QtNetwork import QNetworkProxy -from qutebrowser.misc import objects +from qutebrowser.misc import objects, debugcachestats from qutebrowser.config import configexc, configutils from qutebrowser.utils import (standarddir, utils, qtutils, urlutils, urlmatch, usertypes) @@ -205,6 +205,7 @@ class BaseType: BaseType._basic_str_validation_cache(value) @staticmethod + @debugcachestats.register(name='str validation cache') @functools.lru_cache(maxsize=2**9) def _basic_str_validation_cache(value: str) -> None: """Cache validation result to prevent looping over strings.""" diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py index b90bc22ad..7f6201f88 100644 --- a/qutebrowser/mainwindow/tabwidget.py +++ b/qutebrowser/mainwindow/tabwidget.py @@ -32,7 +32,7 @@ from PyQt5.QtGui import QIcon, QPalette, QColor from qutebrowser.utils import qtutils, objreg, utils, usertypes, log from qutebrowser.config import config -from qutebrowser.misc import objects +from qutebrowser.misc import objects, debugcachestats from qutebrowser.browser import browsertab @@ -569,6 +569,7 @@ class TabBar(QTabBar): icon_width, ellipsis, pinned) + @debugcachestats.register(name='tab width cache') @functools.lru_cache(maxsize=2**9) def _minimum_tab_size_hint_helper(self, tab_text: str, icon_width: int, diff --git a/qutebrowser/misc/debugcachestats.py b/qutebrowser/misc/debugcachestats.py new file mode 100644 index 000000000..d77f3dade --- /dev/null +++ b/qutebrowser/misc/debugcachestats.py @@ -0,0 +1,49 @@ +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2019 Florian Bruhin (The Compiler) <mail@qutebrowser.org> +# +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>. + +"""Implementation of the command debug-cache-stats. + +Because many modules depend on this command, this needs to have as few +dependencies as possible to avoid cyclic dependencies. +""" + +import typing +from typing import TypeVar, Callable + + +# The second element of each tuple should be a lru_cache wrapped function +_CACHE_FUNCTIONS = [] # type: typing.List[typing.Tuple[str, typing.Any]] + + +_T = TypeVar('_T', bound=Callable) + + +def register(name: typing.Optional[str] = None) -> Callable[[_T], _T]: + """Register a lru_cache wrapped function for debug_cache_stats.""" + def wrapper(fn: _T) -> _T: + _CACHE_FUNCTIONS.append((fn.__name__ if name is None else name, fn)) + return fn + return wrapper + + +def debug_cache_stats() -> None: + """Print LRU cache stats.""" + from qutebrowser.utils import log + for name, fn in _CACHE_FUNCTIONS: + log.misc.info('{}: {}'.format(name, fn.cache_info())) diff --git a/qutebrowser/misc/utilcmds.py b/qutebrowser/misc/utilcmds.py index 6f9bf5bd6..a76826d80 100644 --- a/qutebrowser/misc/utilcmds.py +++ b/qutebrowser/misc/utilcmds.py @@ -31,8 +31,7 @@ from qutebrowser.browser import qutescheme from qutebrowser.utils import log, objreg, usertypes, message, debug, utils from qutebrowser.commands import runners from qutebrowser.api import cmdutils -from qutebrowser.config import config, configdata, configtypes -from qutebrowser.misc import consolewidget +from qutebrowser.misc import consolewidget, debugcachestats from qutebrowser.utils.version import pastebin_version from qutebrowser.qt import sip @@ -121,35 +120,7 @@ def debug_all_objects(): @cmdutils.register(debug=True) def debug_cache_stats(): """Print LRU cache stats.""" - prefix_info = configdata.is_valid_prefix.cache_info() - # pylint: disable=protected-access - render_stylesheet_info = config._render_stylesheet.cache_info() - # pylint: enable=protected-access - - history_info = None - try: - from PyQt5.QtWebKit import QWebHistoryInterface - interface = QWebHistoryInterface.defaultInterface() - if interface is not None: - history_info = interface.historyContains.cache_info() - except ImportError: - pass - - tabbed_browser = objreg.get('tabbed-browser', scope='window', - window='last-focused') - # pylint: disable=protected-access - tab_bar = tabbed_browser.widget.tabBar() - tabbed_browser_info = tab_bar._minimum_tab_size_hint_helper.cache_info() - - str_validation_info = (configtypes.BaseType. - _basic_str_validation_cache.cache_info()) - # pylint: enable=protected-access - - log.misc.info('is_valid_prefix: {}'.format(prefix_info)) - log.misc.info('_render_stylesheet: {}'.format(render_stylesheet_info)) - log.misc.info('history: {}'.format(history_info)) - log.misc.info('tab width cache: {}'.format(tabbed_browser_info)) - log.misc.info('str validation cache: {}'.format(str_validation_info)) + debugcachestats.debug_cache_stats() @cmdutils.register(debug=True) diff --git a/scripts/dev/check_coverage.py b/scripts/dev/check_coverage.py index fdbbce71a..6c770adfa 100644 --- a/scripts/dev/check_coverage.py +++ b/scripts/dev/check_coverage.py @@ -202,6 +202,7 @@ PERFECT_FILES = [ # 100% coverage because of end2end tests, but no perfect unit tests yet. WHITELISTED_FILES = [ 'browser/webkit/webkitinspector.py', + 'misc/debugcachestats.py', 'keyinput/macros.py', 'browser/webkit/webkitelem.py', 'api/interceptor.py', |