1
1
mirror of https://github.com/rsms/inter.git synced 2024-11-23 11:43:47 +03:00

tooling: adds a --profile=<file> option to fontbuild for profiling runs and adds misc/tools/fmtprofile.py for printing and inspecting profile results

This commit is contained in:
Rasmus Andersson 2021-03-25 10:49:12 -07:00
parent 034e568938
commit 56cba2d659
3 changed files with 76 additions and 1 deletions

View File

@ -180,6 +180,37 @@ Type `misc/tools/kernsample.py -h` for help on how to use the program.
This only includes existing kerning and is thus only useful for adjustments. Additions must still be done manually. This only includes existing kerning and is thus only useful for adjustments. Additions must still be done manually.
### Performance profiling
`fontbuild` has a `--profile=<file>` option built in which when provided profiles the execution
and writes a pstat file. Example:
```
misc/fontbuild --profile=build/tmp/1.pstat compile -o build/tmp/f.otf build/ufo/Inter-Regular.ufo
```
You can print pstat files with the `fmtprofile.py` tool:
```
misc/tools/fmtprofile.py -n 20 build/tmp/1.pstat
```
You can inspect pstat files interactively with the `pstats` module:
```
python3 -m pstats build/tmp/1.pstat
```
For profiling Python programs that are not fontbuild, you can do this:
```
python -m cProfile -o 1.pstats -s time script.py
```
See <https://docs.python.org/3/library/profile.html> for more information about profiling
Python programs.
### Miscellaneous tools ### Miscellaneous tools
There are several tools included with Inter to help "wrangle" metrics, generate glyphs, create PDFs and so on. You can find these tools in the `misc/tools` directory. They are all command-line tools and their usage can be queried by providing the help flag `-h`. There are several tools included with Inter to help "wrangle" metrics, generate glyphs, create PDFs and so on. You can find these tools in the `misc/tools` directory. They are all command-line tools and their usage can be queried by providing the help flag `-h`.

View File

@ -88,6 +88,9 @@ class Main(object):
argparser.add_argument('-q', '--quiet', action='store_true', argparser.add_argument('-q', '--quiet', action='store_true',
help='Only print errors') help='Only print errors')
argparser.add_argument('--profile', metavar='<file>',
help='Run in profiler for debugging, writing pstats data to <file>')
argparser.add_argument('-C', metavar='<dir>', dest='chdir', argparser.add_argument('-C', metavar='<dir>', dest='chdir',
help='Run as if %(prog)s started in <dir> instead of the '+\ help='Run as if %(prog)s started in <dir> instead of the '+\
'current working directory.') 'current working directory.')
@ -126,7 +129,24 @@ class Main(object):
cmd = 'cmd_' + args.command.replace('-', '_') cmd = 'cmd_' + args.command.replace('-', '_')
if not hasattr(self, cmd): if not hasattr(self, cmd):
fatal('Unrecognized command %s. Try --help' % args.command) fatal('Unrecognized command %s. Try --help' % args.command)
getattr(self, cmd)(argv[i:]) cmdfn = getattr(self, cmd)
if args.profile:
try:
import cProfile as profile
except:
import profile
import __main__
__main__.__dict__["cmdfn"] = cmdfn
__main__.__dict__["argv"] = argv[i:]
profile.run('cmdfn(argv)', args.profile)
print("")
print("profile saved to %r. You can now inspect it with for example:" %
args.profile)
print("misc/tools/fmtprofile.py -n 20 %r" % args.profile)
print("python3 -m pstats %r" % args.profile)
print("")
else:
cmdfn(argv[i:])

24
misc/tools/fmtprofile.py Executable file
View File

@ -0,0 +1,24 @@
#!/usr/bin/env python
# encoding: utf8
#
# Formats a Python profile dump from for example `fontbuild --profile=file ...`
#
import argparse, pstats
from pstats import SortKey
def main():
argparser = argparse.ArgumentParser(description='Formats a Python profile dump')
argparser.add_argument('infile', metavar='<file>', type=str, help='Python pstats file')
argparser.add_argument('-n', '--limit', metavar='N', default=None, type=int,
help='Only print the top N entries')
argparser.add_argument('--sort', metavar='<key>', default=['time'], nargs='+', type=str,
help='Sort by keys (default is time.) Available keys: ' + ', '.join(SortKey))
args = argparser.parse_args()
p = pstats.Stats(args.infile)
p.strip_dirs()
p.sort_stats(SortKey(*args.sort))
p.print_stats(args.limit)
if __name__ == '__main__':
main()