mercurial/policy.py
author Gregory Szorc <gregory.szorc@gmail.com>
Fri, 13 Jan 2017 19:58:00 -0800
changeset 30817 2b279126b8f5
parent 29490 b4d117cee636
child 31317 62939e0148f1
permissions -rw-r--r--
revlog: use compression engine APIs for decompression Now that compression engines declare their header in revlog chunks and can decompress revlog chunks, we refactor revlog.decompress() to use them. Making full use of the property that revlog compressor objects are reusable, revlog instances now maintain a dict mapping an engine's revlog header to a compressor object. This is not only a performance optimization for engines where compressor object reuse can result in better performance, but it also serves as a cache of header values so we don't need to perform redundant lookups against the compression engine manager. (Yes, I measured and the overhead of a function call versus a dict lookup was observed.) Replacing the previous inline lookup table with a dict lookup was measured to make chunk reading ~2.5% slower on changelogs and ~4.5% slower on manifests. So, the inline lookup table has been mostly preserved so we don't lose performance. This is unfortunate. But many decompression operations complete in microseconds, so Python attribute lookup, dict lookup, and function calls do matter. The impact of this change on mozilla-unified is as follows: $ hg perfrevlogchunks -c ! chunk ! wall 1.953663 comb 1.950000 user 1.920000 sys 0.030000 (best of 6) ! wall 1.946000 comb 1.940000 user 1.910000 sys 0.030000 (best of 6) ! chunk batch ! wall 1.791075 comb 1.800000 user 1.760000 sys 0.040000 (best of 6) ! wall 1.785690 comb 1.770000 user 1.750000 sys 0.020000 (best of 6) $ hg perfrevlogchunks -m ! chunk ! wall 2.587262 comb 2.580000 user 2.550000 sys 0.030000 (best of 4) ! wall 2.616330 comb 2.610000 user 2.560000 sys 0.050000 (best of 4) ! chunk batch ! wall 2.427092 comb 2.420000 user 2.400000 sys 0.020000 (best of 5) ! wall 2.462061 comb 2.460000 user 2.400000 sys 0.060000 (best of 4) Changelog chunk reading is slightly faster but manifest reading is slower. What gives? On this repo, 99.85% of changelog entries are zlib compressed (the 'x' header). On the manifest, 67.5% are zlib and 32.4% are '\0'. This patch swapped the test order of 'x' and '\0' so now 'x' is tested first. This makes changelogs faster since they almost always hit the first branch. This makes a significant percentage of manifest '\0' chunks slower because that code path now performs an extra test. Yes, I too can't believe we're able to measure the impact of an if..elif with simple string compares. I reckon this code would benefit from being written in C...
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
29266
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
     1
# policy.py - module policy logic for Mercurial.
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
     2
#
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
     3
# Copyright 2015 Gregory Szorc <gregory.szorc@gmail.com>
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
     4
#
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
     7
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
     8
from __future__ import absolute_import
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
     9
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    10
import os
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    11
import sys
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    12
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    13
# Rules for how modules can be loaded. Values are:
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    14
#
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    15
#    c - require C extensions
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    16
#    allow - allow pure Python implementation when C loading fails
29490
b4d117cee636 policy: add cffi policy for PyPy
Maciej Fijalkowski <fijall@gmail.com>
parents: 29266
diff changeset
    17
#    cffi - required cffi versions (implemented within pure module)
b4d117cee636 policy: add cffi policy for PyPy
Maciej Fijalkowski <fijall@gmail.com>
parents: 29266
diff changeset
    18
#    cffi-allow - allow pure Python implementation if cffi version is missing
29266
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    19
#    py - only load pure Python modules
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    20
#
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    21
# By default, require the C extensions for performance reasons.
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    22
policy = 'c'
29490
b4d117cee636 policy: add cffi policy for PyPy
Maciej Fijalkowski <fijall@gmail.com>
parents: 29266
diff changeset
    23
policynoc = ('cffi', 'cffi-allow', 'py')
b4d117cee636 policy: add cffi policy for PyPy
Maciej Fijalkowski <fijall@gmail.com>
parents: 29266
diff changeset
    24
policynocffi = ('c', 'py')
b4d117cee636 policy: add cffi policy for PyPy
Maciej Fijalkowski <fijall@gmail.com>
parents: 29266
diff changeset
    25
29266
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    26
try:
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    27
    from . import __modulepolicy__
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    28
    policy = __modulepolicy__.modulepolicy
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    29
except ImportError:
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    30
    pass
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    31
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    32
# PyPy doesn't load C extensions.
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    33
#
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    34
# The canonical way to do this is to test platform.python_implementation().
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    35
# But we don't import platform and don't bloat for it here.
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    36
if '__pypy__' in sys.builtin_module_names:
29490
b4d117cee636 policy: add cffi policy for PyPy
Maciej Fijalkowski <fijall@gmail.com>
parents: 29266
diff changeset
    37
    policy = 'cffi'
29266
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    38
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    39
# Our C extensions aren't yet compatible with Python 3. So use pure Python
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    40
# on Python 3 for now.
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    41
if sys.version_info[0] >= 3:
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    42
    policy = 'py'
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    43
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    44
# Environment variable can always force settings.
b3a677c82a35 debuginstall: expose modulepolicy
timeless <timeless@mozdev.org>
parents:
diff changeset
    45
policy = os.environ.get('HGMODULEPOLICY', policy)