diff options
author | Nirbheek Chauhan <nirbheek@centricular.com> | 2018-09-11 17:32:31 +0530 |
---|---|---|
committer | Nirbheek Chauhan <nirbheek.chauhan@gmail.com> | 2018-09-11 10:19:42 -0700 |
commit | 1af704a509619d30b1fd9c6f96909c8195c0e3ca (patch) | |
tree | a6ff08a720ffdb106f54ee715b3a689b58fba119 | |
parent | d67ec95b500aabe0da5d95860fcefb894b7d363b (diff) | |
download | meson-1af704a509619d30b1fd9c6f96909c8195c0e3ca.zip meson-1af704a509619d30b1fd9c6f96909c8195c0e3ca.tar.gz meson-1af704a509619d30b1fd9c6f96909c8195c0e3ca.tar.bz2 |
Sprinkle functools.lru_cache() in a few more places
This improves the backend generation time for gst-build from 7.4s to
6.6s. This is probably all the low-hanging fruit we can get, further
improvements will probably require refactoring, moving to pathlib.Path
or reimplementing CompilerArgs:
222045 0.551 0.000 1.324 0.000 compilers.py:666(__iadd__)
3691 0.230 0.000 0.885 0.000 ninjabackend.py:99(write)
233560 0.441 0.000 0.701 0.000 posixpath.py:75(join)
882 0.141 0.000 0.636 0.001 backends.py:509(generate_basic_compiler_args)
256301 0.248 0.000 0.576 0.000 compilers.py:562(_can_dedup)
37369 0.035 0.000 0.466 0.000 compilers.py:652(extend_direct)
74650 0.067 0.000 0.431 0.000 compilers.py:641(append_direct)
158153 0.089 0.000 0.405 0.000 ninjabackend.py:129(<lambda>)
845 0.064 0.000 0.391 0.000 ninjabackend.py:279(get_target_generated_sources)
58161 0.070 0.000 0.317 0.000 backends.py:217(get_target_generated_dir)
216825 0.175 0.000 0.275 0.000 ninjabackend.py:48(ninja_quote)
845 0.058 0.000 0.255 0.000 ninjabackend.py:2289(guess_external_link_dependencies)
845 0.068 0.000 0.239 0.000 backends.py:793(get_custom_target_provided_libraries)
52101 0.030 0.000 0.237 0.000 compilers.py:716(append)
1319326 0.231 0.000 0.231 0.000 {built-in method builtins.isinstance}
1189117 0.229 0.000 0.229 0.000 {method 'startswith' of 'str' objects}
3235 0.102 0.000 0.228 0.000 compilers.py:614(to_native)
Note: there are 845 build targets.
-rw-r--r-- | mesonbuild/backend/backends.py | 3 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 13 | ||||
-rw-r--r-- | mesonbuild/compilers/c.py | 19 | ||||
-rw-r--r-- | mesonbuild/compilers/compilers.py | 10 | ||||
-rwxr-xr-x | run_unittests.py | 22 |
5 files changed, 30 insertions, 37 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 8153ff7..0e7e8e0 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -17,7 +17,6 @@ from .. import build from .. import dependencies from .. import mesonlib from .. import mlog -from .. import compilers import json import subprocess from ..mesonlib import MesonException, OrderedSet @@ -400,7 +399,7 @@ class Backend: result = OrderedSet() result.add('meson-out') result.update(self.rpaths_for_bundled_shared_libraries(target)) - return list(result) + return tuple(result) def object_filename_from_source(self, target, source): assert isinstance(source, mesonlib.File) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 6daa939..6b2a00a 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -20,6 +20,7 @@ import subprocess from collections import OrderedDict import itertools from pathlib import PurePath +from functools import lru_cache from . import backends from .. import modules @@ -147,7 +148,6 @@ class NinjaBackend(backends.Backend): super().__init__(build) self.name = 'ninja' self.ninja_filename = 'build.ninja' - self.target_arg_cache = {} self.fortran_deps = {} self.all_outputs = {} @@ -1951,6 +1951,7 @@ rule FORTRAN_DEP_HACK%s incs += compiler.get_include_args(i, False) return incs + @lru_cache(maxsize=None) def _generate_single_compile(self, target, compiler, is_generated=False): base_proxy = self.get_base_options_for_target(target) # Create an empty commands list, and start adding arguments from @@ -2047,12 +2048,7 @@ rule FORTRAN_DEP_HACK%s raise AssertionError('BUG: sources should not contain headers {!r}'.format(src)) compiler = get_compiler_for_source(target.compilers.values(), src) - key = (target, compiler, is_generated) - if key in self.target_arg_cache: - commands = self.target_arg_cache[key] - else: - commands = self._generate_single_compile(target, compiler, is_generated) - self.target_arg_cache[key] = commands + commands = self._generate_single_compile(target, compiler, is_generated) commands = CompilerArgs(commands.compiler, commands) build_dir = self.environment.get_build_dir() @@ -2276,6 +2272,7 @@ rule FORTRAN_DEP_HACK%s return linker.get_link_whole_for(target_args) if len(target_args) else [] @staticmethod + @lru_cache(maxsize=None) def guess_library_absolute_path(linker, libname, search_dirs, patterns): for d in search_dirs: for p in patterns: @@ -2334,7 +2331,7 @@ rule FORTRAN_DEP_HACK%s guessed_dependencies = [] # TODO The get_library_naming requirement currently excludes link targets that use d or fortran as their main linker if hasattr(linker, 'get_library_naming'): - search_dirs = list(search_dirs) + linker.get_library_dirs(self.environment) + search_dirs = tuple(search_dirs) + linker.get_library_dirs(self.environment) static_patterns = linker.get_library_naming(self.environment, 'static', strict=True) shared_patterns = linker.get_library_naming(self.environment, 'shared', strict=True) for libname in libs: diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index bde9f63..1d531a6 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -119,6 +119,7 @@ class CCompiler(Compiler): return None, fname # The default behavior is this, override in MSVC + @functools.lru_cache(maxsize=None) def build_rpath_args(self, build_dir, from_dir, rpath_paths, build_rpath, install_rpath): if self.id == 'clang' and self.clang_type == compilers.CLANG_OSX: return self.build_osx_rpath_args(build_dir, rpath_paths, build_rpath) @@ -222,7 +223,7 @@ class CCompiler(Compiler): p = Path(p) if p.exists(): paths.append(p.resolve().as_posix()) - return paths + return tuple(paths) def get_compiler_dirs(self, env, name): ''' @@ -232,23 +233,19 @@ class CCompiler(Compiler): for line in stdo.split('\n'): if line.startswith(name + ':'): return CCompiler._split_fetch_real_dirs(line.split('=', 1)[1]) - return [] + return () + @functools.lru_cache() def get_library_dirs(self, env): - key = (tuple(self.exelist), env) - if key not in self.library_dirs_cache: - self.library_dirs_cache[key] = self.get_compiler_dirs(env, 'libraries') - return self.library_dirs_cache[key][:] + return self.get_compiler_dirs(env, 'libraries') + @functools.lru_cache() def get_program_dirs(self, env): ''' Programs used by the compiler. Also where toolchain DLLs such as libstdc++-6.dll are found with MinGW. ''' - key = (tuple(self.exelist), env) - if key not in self.program_dirs_cache: - self.program_dirs_cache[key] = self.get_compiler_dirs(env, 'programs') - return self.program_dirs_cache[key][:] + return self.get_compiler_dirs(env, 'programs') def get_pic_args(self): return ['-fPIC'] @@ -907,7 +904,7 @@ class CCompiler(Compiler): patterns += self._get_patterns(env, prefixes, stlibext, False) else: raise AssertionError('BUG: unknown libtype {!r}'.format(libtype)) - return patterns + return tuple(patterns) @staticmethod def _sort_shlibs_openbsd(libs): diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 88e9bce..40d6880 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -923,7 +923,7 @@ class Compiler: raise EnvironmentException('Language {} does not support library finding.'.format(self.get_display_language())) def get_library_dirs(self, *args, **kwargs): - return [] + return () def has_multi_arguments(self, args, env): raise EnvironmentException( @@ -1381,12 +1381,12 @@ class ElbrusCompiler(GnuCompiler): os_env = os.environ.copy() os_env['LC_ALL'] = 'C' stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=os_env)[1] - paths = [] + paths = () for line in stdo.split('\n'): if line.startswith('libraries:'): # lcc does not include '=' in --print-search-dirs output. libstr = line.split(' ', 1)[1] - paths = [os.path.realpath(p) for p in libstr.split(':')] + paths = (os.path.realpath(p) for p in libstr.split(':')) break return paths @@ -1394,12 +1394,12 @@ class ElbrusCompiler(GnuCompiler): os_env = os.environ.copy() os_env['LC_ALL'] = 'C' stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=os_env)[1] - paths = [] + paths = () for line in stdo.split('\n'): if line.startswith('programs:'): # lcc does not include '=' in --print-search-dirs output. libstr = line.split(' ', 1)[1] - paths = [os.path.realpath(p) for p in libstr.split(':')] + paths = (os.path.realpath(p) for p in libstr.split(':')) break return paths diff --git a/run_unittests.py b/run_unittests.py index 145d9b5..79bafcd 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -575,22 +575,22 @@ class InternalTests(unittest.TestCase): ''' Unit test for the library search patterns used by find_library() ''' - unix_static = ['lib{}.a', '{}.a'] - msvc_static = ['lib{}.a', 'lib{}.lib', '{}.a', '{}.lib'] + unix_static = ('lib{}.a', '{}.a') + msvc_static = ('lib{}.a', 'lib{}.lib', '{}.a', '{}.lib') # This is the priority list of pattern matching for library searching - patterns = {'openbsd': {'shared': ['lib{}.so', '{}.so', 'lib{}.so.[0-9]*.[0-9]*'], + patterns = {'openbsd': {'shared': ('lib{}.so', '{}.so', 'lib{}.so.[0-9]*.[0-9]*'), 'static': unix_static}, - 'linux': {'shared': ['lib{}.so', '{}.so'], + 'linux': {'shared': ('lib{}.so', '{}.so'), 'static': unix_static}, - 'darwin': {'shared': ['lib{}.dylib', '{}.dylib'], + 'darwin': {'shared': ('lib{}.dylib', '{}.dylib'), 'static': unix_static}, - 'cygwin': {'shared': ['cyg{}.dll', 'cyg{}.dll.a', 'lib{}.dll', - 'lib{}.dll.a', '{}.dll', '{}.dll.a'], - 'static': ['cyg{}.a'] + unix_static}, - 'windows-msvc': {'shared': ['lib{}.lib', '{}.lib'], + 'cygwin': {'shared': ('cyg{}.dll', 'cyg{}.dll.a', 'lib{}.dll', + 'lib{}.dll.a', '{}.dll', '{}.dll.a'), + 'static': ('cyg{}.a',) + unix_static}, + 'windows-msvc': {'shared': ('lib{}.lib', '{}.lib'), 'static': msvc_static}, - 'windows-mingw': {'shared': ['lib{}.dll.a', 'lib{}.lib', 'lib{}.dll', - '{}.dll.a', '{}.lib', '{}.dll'], + 'windows-mingw': {'shared': ('lib{}.dll.a', 'lib{}.lib', 'lib{}.dll', + '{}.dll.a', '{}.lib', '{}.dll'), 'static': msvc_static}} env = get_fake_env('', '', '') cc = env.detect_c_compiler(False) |