Description
Details
Subject | Repo | Branch | Lines +/- | |
---|---|---|---|---|
Add threads parameter to captcha.py for multithread CAPTCHA generation | mediawiki/extensions/ConfirmEdit | master | +86 -25 |
Status | Subtype | Assigned | Task | ||
---|---|---|---|---|---|
Restricted Task | |||||
Open | None | T150049 Enable $wgCaptchaDeleteOnSolve | |||
Resolved | Reedy | T157736 Speed up captcha generation | |||
Resolved | Florian | T157734 Add threading to captcha.py | |||
Resolved | Reedy | T157737 Add timing instrumentation to GenerateFancyCaptchas.php |
Event Timeline
Change 337057 had a related patch set uploaded (by Florianschmidtwelzow):
Add threads parameter to captcha.py for multithread CAPTCHA generation
To generate 10k captchas, using WMF wordlists etc etc...
On a single core vm. 2299.984 MHz
real 43m31.650s user 41m54.592s sys 0m33.300s
on terbium, 6 (12 threads with HT) core E 5-2440 at 2.4 GHz
real 26m41.157s user 26m31.411s sys 0m7.561s
Will test it with > 1 thread with Florians patch to see the improvement it makes
Great, thanks @Reedy for the test. I can't await the results with multiple threads :)
Well, this is fun...
reedy@terbium:~$ time python 'captcha-old.py' --key 'CHANGE_THIS_SECRET!' --output '/tmp/mw-fancycaptcha-1486771866-0b4ca9' --count '10000' --dirs '0' --wordlist '/etc/fancycaptcha/words' --font '/usr/share/fonts/truetype/freefont/FreeMonoBoldOblique.ttf' --blacklist '/etc/fancycaptcha/badwords' --threads 2 Generating 10000 CAPTCHA images separated in 5000 image(s) per chunk run by 2 threads... real 26m39.426s user 36m26.436s sys 1m32.109s
reedy@terbium:~$ time python 'captcha-old.py' --key 'CHANGE_THIS_SECRET!' --output '/tmp/mw-fancycaptcha-1486771866-0b4ca9' --count '10000' --dirs '0' --wordlist '/etc/fancycaptcha/words' --font '/usr/share/fonts/truetype/freefont/FreeMonoBoldOblique.ttf' --blacklist '/etc/fancycaptcha/badwords' --threads 4 Generating 10000 CAPTCHA images separated in 2500 image(s) per chunk run by 4 threads... real 25m20.317s user 40m33.306s sys 4m5.107s
reedy@terbium:~$ time python 'captcha-old.py' --key 'CHANGE_THIS_SECRET!' --output '/tmp/mw-fancycaptcha-1486771866-0b4ca9' --count '10000' --dirs '0' --wordlist '/etc/fancycaptcha/words' --font '/usr/share/fonts/truetype/freefont/FreeMonoBoldOblique.ttf' --blacklist '/etc/fancycaptcha/badwords' --threads 8 Generating 10000 CAPTCHA images separated in 1250 image(s) per chunk run by 8 threads... real 30m46.742s user 49m30.369s sys 7m3.802s
So based on this... Multi threading, at least, in it's current implementation, makes no improvement? :(
@Florian Do you have any python benchmarking/profiling tools? It'd be interesting to see what parts (of the single threaded version) is taking the time, and if there's anything we can do to improve it
I'll deploy my backport of the instrumentation to the php script, and have a look at what % of the overall time this takes....
Kind of, I wanted to test it on the version we're running in production, so copied his changes to the old copy of the script to test the multithreading
https://github.com/wikimedia/mediawiki-extensions-ConfirmEdit/blob/master/captcha.py vs https://github.com/wikimedia/mediawiki-extensions-ConfirmEdit/blob/master/captcha-old.py
For 100 images...
reedy@terbium:~$ time python -m cProfile -s cumtime 'captcha-old.py' --key 'CHANGE_THIS_SECRET!' --output '/tmp/mw-fancycaptcha-1486771866-0b4ca9' --count '100' --dirs '0' --wordlist '/etc/fancycaptcha/words' --font '/usr/share/fonts/truetype/freefont/FreeMonoBoldOblique.ttf' --blacklist '/etc/fancycaptcha/badwords' Generating 100 CAPTCHA images separated in 100 image(s) per chunk run by 1 threads... 302199 function calls (302198 primitive calls) in 16.427 seconds Ordered by: cumulative time ncalls tottime percall cumtime percall filename:lineno(function) 1 0.023 0.023 16.427 16.427 captcha-old.py:28(<module>) 160 16.336 0.102 16.336 0.102 {time.sleep} 2 0.028 0.014 0.052 0.026 captcha-old.py:175(read_wordlist) 100052 0.011 0.000 0.011 0.000 {method 'lower' of 'str' objects} 100048 0.008 0.000 0.008 0.000 {method 'strip' of 'str' objects} 2 0.006 0.003 0.006 0.003 {method 'readlines' of 'file' objects} 99639 0.005 0.000 0.005 0.000 {len} 1 0.001 0.001 0.004 0.004 Image.py:1(<module>) 1 0.001 0.001 0.003 0.003 Image.py:27(<module>) 1 0.000 0.000 0.002 0.002 {__import__} 1 0.000 0.000 0.002 0.002 FixTk.py:1(<module>) 161 0.001 0.000 0.001 0.000 threading.py:1167(activeCount) 1 0.001 0.001 0.001 0.001 __init__.py:4(<module>) 1 0.000 0.000 0.001 0.001 threading.py:726(start) 1 0.000 0.000 0.001 0.001 threading.py:602(wait) 1 0.000 0.000 0.001 0.001 threading.py:308(wait) 7 0.001 0.000 0.001 0.000 {method 'acquire' of 'thread.lock' objects} 1 0.000 0.000 0.001 0.001 threading.py:1(<module>) 1 0.000 0.000 0.001 0.001 random.py:40(<module>) 1 0.000 0.000 0.001 0.001 ImageEnhance.py:1(<module>) 1 0.000 0.000 0.001 0.001 ImageEnhance.py:21(<module>) 1 0.000 0.000 0.000 0.000 numbers.py:6(<module>) 1 0.000 0.000 0.000 0.000 hashlib.py:55(<module>) 1 0.000 0.000 0.000 0.000 ImageFont.py:1(<module>) 1 0.000 0.000 0.000 0.000 ImageFilter.py:18(<module>) 16 0.000 0.000 0.000 0.000 optparse.py:1008(add_option) 1 0.000 0.000 0.000 0.000 collections.py:1(<module>) 1 0.000 0.000 0.000 0.000 optparse.py:1191(__init__) 3 0.000 0.000 0.000 0.000 re.py:188(compile) 3 0.000 0.000 0.000 0.000 re.py:226(_compile) 5 0.000 0.000 0.000 0.000 abc.py:86(__new__) 3 0.000 0.000 0.000 0.000 sre_compile.py:493(compile) 1 0.000 0.000 0.000 0.000 ImageFont.py:28(<module>) 2 0.000 0.000 0.000 0.000 gettext.py:580(gettext) 2 0.000 0.000 0.000 0.000 gettext.py:542(dgettext) 16 0.000 0.000 0.000 0.000 optparse.py:561(__init__) 2 0.000 0.000 0.000 0.000 gettext.py:476(translation) 2 0.000 0.000 0.000 0.000 gettext.py:421(find) 1 0.000 0.000 0.000 0.000 warnings.py:45(filterwarnings) 1 0.000 0.000 0.000 0.000 ImageDraw.py:1(<module>) 1 0.000 0.000 0.000 0.000 __init__.py:265(_reset_cache) 1 0.000 0.000 0.000 0.000 optparse.py:1258(_populate_option_list) 1 0.000 0.000 0.000 0.000 optparse.py:1248(_add_help_option) 1 0.000 0.000 0.000 0.000 optparse.py:1277(set_usage) 3 0.000 0.000 0.000 0.000 sre_compile.py:478(_code) 3 0.000 0.000 0.000 0.000 sre_parse.py:675(parse) 1 0.000 0.000 0.000 0.000 ImageDraw.py:33(<module>) 2 0.000 0.000 0.000 0.000 threading.py:656(__init__) 1 0.000 0.000 0.000 0.000 optparse.py:1368(parse_args) 3 0.000 0.000 0.000 0.000 sre_parse.py:301(_parse_sub) 1 0.000 0.000 0.000 0.000 heapq.py:31(<module>) 1 0.000 0.000 0.000 0.000 ImageOps.py:1(<module>) 3 0.000 0.000 0.000 0.000 sre_parse.py:379(_parse) 23 0.000 0.000 0.000 0.000 genericpath.py:15(exists) 4 0.000 0.000 0.000 0.000 abc.py:105(register) 14 0.000 0.000 0.000 0.000 __init__.py:147(_check_size) 16 0.000 0.000 0.000 0.000 optparse.py:610(_set_attrs) 5 0.000 0.000 0.000 0.000 {built-in method __new__ of type object at 0x91d400} 3 0.000 0.000 0.000 0.000 sre_compile.py:359(_compile_info) 25 0.000 0.000 0.000 0.000 posixpath.py:68(join) 10/9 0.000 0.000 0.000 0.000 {issubclass} 3 0.000 0.000 0.000 0.000 __init__.py:78(CFUNCTYPE) 4 0.000 0.000 0.000 0.000 abc.py:148(__subclasscheck__) 1 0.000 0.000 0.000 0.000 optparse.py:1420(_process_args) 2 0.000 0.000 0.000 0.000 sre_compile.py:178(_compile_charset) 6 0.000 0.000 0.000 0.000 gettext.py:130(_expand_lang) 7 0.000 0.000 0.000 0.000 optparse.py:1480(_process_long_opt) 1 0.000 0.000 0.000 0.000 threading.py:1090(__init__) 215 0.000 0.000 0.000 0.000 {getattr} 2 0.000 0.000 0.000 0.000 sre_compile.py:207(_optimize_charset) 1 0.000 0.000 0.000 0.000 _endian.py:4(<module>) 23 0.000 0.000 0.000 0.000 {posix.stat} 46 0.000 0.000 0.000 0.000 abc.py:89(<genexpr>) 1 0.000 0.000 0.000 0.000 random.py:91(__init__) 2 0.000 0.000 0.000 0.000 threading.py:541(Event) 1 0.000 0.000 0.000 0.000 random.py:100(seed) 1 0.000 0.000 0.000 0.000 {thread.start_new_thread} 3 0.000 0.000 0.000 0.000 sre_compile.py:32(_compile) 3 0.000 0.000 0.000 0.000 __init__.py:493(PYFUNCTYPE) 4 0.000 0.000 0.000 0.000 threading.py:241(Condition) 2 0.000 0.000 0.000 0.000 threading.py:560(__init__) 32 0.000 0.000 0.000 0.000 sre_parse.py:201(get) 4 0.000 0.000 0.000 0.000 threading.py:259(__init__) 1 0.000 0.000 0.000 0.000 ImageStat.py:24(<module>) 1 0.000 0.000 0.000 0.000 optparse.py:1319(get_default_values) 2 0.000 0.000 0.000 0.000 {_ctypes.POINTER} 37 0.000 0.000 0.000 0.000 sre_parse.py:182(__next) 1 0.000 0.000 0.000 0.000 posixpath.py:379(realpath) 7 0.000 0.000 0.000 0.000 optparse.py:779(process) 1 0.000 0.000 0.000 0.000 __init__.py:349(__init__) 16 0.000 0.000 0.000 0.000 optparse.py:636(_check_type) 16 0.000 0.000 0.000 0.000 optparse.py:589(_set_opt_strings) 2 0.000 0.000 0.000 0.000 posixpath.py:365(abspath) 5 0.000 0.000 0.000 0.000 _weakrefset.py:58(__iter__) 16 0.000 0.000 0.000 0.000 _weakrefset.py:36(__init__) 1 0.000 0.000 0.000 0.000 ImageColor.py:20(<module>) 214 0.000 0.000 0.000 0.000 {setattr} 7 0.000 0.000 0.000 0.000 optparse.py:772(convert_value) 16 0.000 0.000 0.000 0.000 optparse.py:679(_check_dest) 185 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects} 1 0.000 0.000 0.000 0.000 _util.py:1(<module>) 1 0.000 0.000 0.000 0.000 {posix.urandom} 1 0.000 0.000 0.000 0.000 threading.py:296(_acquire_restore) 2 0.000 0.000 0.000 0.000 posixpath.py:336(normpath) 1 0.000 0.000 0.000 0.000 numbers.py:34(Complex) 3 0.000 0.000 0.000 0.000 sre_parse.py:140(getwidth) 6 0.000 0.000 0.000 0.000 hashlib.py:94(__get_openssl_constructor) 18 0.000 0.000 0.000 0.000 {_struct.calcsize} 42 0.000 0.000 0.000 0.000 {isinstance} 6 0.000 0.000 0.000 0.000 locale.py:363(normalize) 1 0.000 0.000 0.000 0.000 posixpath.py:387(_joinrealpath) 8 0.000 0.000 0.000 0.000 optparse.py:765(check_value) 1 0.000 0.000 0.000 0.000 ImageOps.py:20(<module>) 1 0.000 0.000 0.000 0.000 threading.py:640(Thread) 1 0.000 0.000 0.000 0.000 {function seed at 0x7fc6d94b0ed8} 16 0.000 0.000 0.000 0.000 optparse.py:580(_check_opt_strings) 66 0.000 0.000 0.000 0.000 {method 'endswith' of 'str' objects} 68 0.000 0.000 0.000 0.000 {method 'add' of 'set' objects} 2 0.000 0.000 0.000 0.000 {method 'close' of 'file' objects} 74 0.000 0.000 0.000 0.000 {method 'startswith' of 'str' objects} 1 0.000 0.000 0.000 0.000 __future__.py:48(<module>) 2 0.000 0.000 0.000 0.000 {open} 1 0.000 0.000 0.000 0.000 threading.py:575(set) 1 0.000 0.000 0.000 0.000 optparse.py:366(__init__) 23 0.000 0.000 0.000 0.000 sre_parse.py:138(append) 1 0.000 0.000 0.000 0.000 threading.py:709(_set_daemon) 1 0.000 0.000 0.000 0.000 numbers.py:295(Integral) 1 0.000 0.000 0.000 0.000 {math.exp} 37 0.000 0.000 0.000 0.000 {method 'get' of 'dict' objects} 16 0.000 0.000 0.000 0.000 optparse.py:981(_check_conflict) 1 0.000 0.000 0.000 0.000 optparse.py:200(__init__) 3 0.000 0.000 0.000 0.000 sre_parse.py:178(__init__) 4 0.000 0.000 0.000 0.000 _weakrefset.py:26(__exit__) 37 0.000 0.000 0.000 0.000 abc.py:15(abstractmethod) 1 0.000 0.000 0.000 0.000 Image.py:447(Image) 8 0.000 0.000 0.000 0.000 _weakrefset.py:83(add) 1 0.000 0.000 0.000 0.000 optparse.py:838(__init__) 2 0.000 0.000 0.000 0.000 optparse.py:424(check_builtin) 1 0.000 0.000 0.000 0.000 threading.py:399(notifyAll) 2 0.000 0.000 0.000 0.000 optparse.py:413(_parse_int) 9 0.000 0.000 0.000 0.000 {method 'items' of 'dict' objects} 1 0.000 0.000 0.000 0.000 posixpath.py:139(islink) 10 0.000 0.000 0.000 0.000 {hasattr} 8 0.000 0.000 0.000 0.000 threading.py:58(__init__) 2 0.000 0.000 0.000 0.000 {math.log} 7 0.000 0.000 0.000 0.000 _weakrefset.py:70(__contains__) 1 0.000 0.000 0.000 0.000 collections.py:26(OrderedDict) 7 0.000 0.000 0.000 0.000 optparse.py:1471(_match_long_opt) 15 0.000 0.000 0.000 0.000 {method 'replace' of 'str' objects} 4 0.000 0.000 0.000 0.000 _weakrefset.py:20(__enter__) 16 0.000 0.000 0.000 0.000 optparse.py:666(_check_choice) 1 0.000 0.000 0.000 0.000 random.py:72(Random) 9 0.000 0.000 0.000 0.000 {range} 1 0.000 0.000 0.000 0.000 numbers.py:169(Real) 16 0.000 0.000 0.000 0.000 optparse.py:833(isbasestring) 2 0.000 0.000 0.000 0.000 UserDict.py:58(get) 1 0.000 0.000 0.000 0.000 threading.py:627(_newname) 15 0.000 0.000 0.000 0.000 {method 'pop' of 'list' objects} 18 0.000 0.000 0.000 0.000 {method 'find' of 'str' objects} 2 0.000 0.000 0.000 0.000 optparse.py:400(_parse_num) 16 0.000 0.000 0.000 0.000 optparse.py:709(_check_callback) 38 0.000 0.000 0.000 0.000 {_ctypes.sizeof} 6 0.000 0.000 0.000 0.000 sre_compile.py:472(isstring) 1 0.000 0.000 0.000 0.000 threading.py:1035(setDaemon) 3 0.000 0.000 0.000 0.000 sre_parse.py:67(__init__) 1 0.000 0.000 0.000 0.000 posixpath.py:127(dirname) 1 0.000 0.000 0.000 0.000 threading.py:1152(currentThread) 1 0.000 0.000 0.000 0.000 keyword.py:11(<module>) 16 0.000 0.000 0.000 0.000 {filter} 1 0.000 0.000 0.000 0.000 numbers.py:270(Rational) 3 0.000 0.000 0.000 0.000 {_sre.compile} 16 0.000 0.000 0.000 0.000 optparse.py:700(_check_nargs) 1 0.000 0.000 0.000 0.000 optparse.py:933(__init__) 1 0.000 0.000 0.000 0.000 threading.py:372(notify) 7 0.000 0.000 0.000 0.000 optparse.py:1675(_match_abbrev) 16 0.000 0.000 0.000 0.000 optparse.py:694(_check_const) 5 0.000 0.000 0.000 0.000 sre_parse.py:195(match) 1 0.000 0.000 0.000 0.000 ImageDraw.py:49(ImageDraw) 1 0.000 0.000 0.000 0.000 ImageMode.py:17(<module>) 7 0.000 0.000 0.000 0.000 optparse.py:791(take_action) 1 0.000 0.000 0.000 0.000 {posix.lstat} 4 0.000 0.000 0.000 0.000 {method 'split' of 'str' objects} 1 0.000 0.000 0.000 0.000 {binascii.hexlify} 1 0.000 0.000 0.000 0.000 threading.py:422(_Semaphore) 2 0.000 0.000 0.000 0.000 threading.py:299(_is_owned) 1 0.000 0.000 0.000 0.000 _binary.py:14(<module>) 1 0.000 0.000 0.000 0.000 {_ctypes.dlopen} 1 0.000 0.000 0.000 0.000 threading.py:1024(daemon) 3 0.000 0.000 0.000 0.000 UserDict.py:18(__getitem__) 1 0.000 0.000 0.000 0.000 {sorted} 2 0.000 0.000 0.000 0.000 {method 'setter' of 'property' objects} 7 0.000 0.000 0.000 0.000 {min} 16 0.000 0.000 0.000 0.000 optparse.py:630(_check_action) 3 0.000 0.000 0.000 0.000 posixpath.py:59(isabs) 1 0.000 0.000 0.000 0.000 collections.py:387(Counter) 3 0.000 0.000 0.000 0.000 threading.py:63(_note) 1 0.000 0.000 0.000 0.000 threading.py:293(_release_save) 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_md5} 1 0.000 0.000 0.000 0.000 threading.py:789(_set_ident) 7 0.000 0.000 0.000 0.000 optparse.py:753(takes_value) 1 0.000 0.000 0.000 0.000 {posix.getcwd} 6 0.000 0.000 0.000 0.000 {globals} 2 0.000 0.000 0.000 0.000 {method 'clear' of 'dict' objects} 1 0.000 0.000 0.000 0.000 ImageFont.py:120(FreeTypeFont) 23 0.000 0.000 0.000 0.000 {ord} 4 0.000 0.000 0.000 0.000 _weakrefset.py:52(_commit_removals) 1 0.000 0.000 0.000 0.000 ImageFilter.py:113(MaxFilter) 6 0.000 0.000 0.000 0.000 {thread.allocate_lock} 2 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects} 4 0.000 0.000 0.000 0.000 _weakrefset.py:16(__init__) 12 0.000 0.000 0.000 0.000 {_sre.getlower} 3 0.000 0.000 0.000 0.000 __init__.py:494(CFunctionType) 1 0.000 0.000 0.000 0.000 threading.py:124(_RLock) 6 0.000 0.000 0.000 0.000 {method 'translate' of 'str' objects} 7 0.000 0.000 0.000 0.000 __future__.py:75(__init__) 3 0.000 0.000 0.000 0.000 __init__.py:104(CFunctionType) 1 0.000 0.000 0.000 0.000 {math.sqrt} 1 0.000 0.000 0.000 0.000 ImageStat.py:29(Stat) 6 0.000 0.000 0.000 0.000 {method 'reverse' of 'list' objects} 1 0.000 0.000 0.000 0.000 optparse.py:1243(_create_option_list) 6 0.000 0.000 0.000 0.000 {method 'pop' of 'dict' objects} 1 0.000 0.000 0.000 0.000 threading.py:1058(_Timer) 1 0.000 0.000 0.000 0.000 __init__.py:294(c_wchar) 1 0.000 0.000 0.000 0.000 {method 'partition' of 'str' objects} 1 0.000 0.000 0.000 0.000 threading.py:551(_Event) 1 0.000 0.000 0.000 0.000 ImageEnhance.py:66(Brightness) 1 0.000 0.000 0.000 0.000 ImageFilter.py:127(ModeFilter) 1 0.000 0.000 0.000 0.000 ImageFilter.py:145(GaussianBlur) 1 0.000 0.000 0.000 0.000 {method 'rfind' of 'str' objects} 1 0.000 0.000 0.000 0.000 __init__.py:359(_FuncPtr) 1 0.000 0.000 0.000 0.000 ImageFilter.py:57(BuiltinFilter) 1 0.000 0.000 0.000 0.000 __init__.py:189(c_int) 1 0.000 0.000 0.000 0.000 optparse.py:1268(_init_parsing_state) 1 0.000 0.000 0.000 0.000 ImageMode.py:22(ModeDescriptor) 1 0.000 0.000 0.000 0.000 __init__.py:291(c_wchar_p) 1 0.000 0.000 0.000 0.000 __init__.py:238(c_char) 1 0.000 0.000 0.000 0.000 random.py:800(SystemRandom) 1 0.000 0.000 0.000 0.000 {method 'keys' of 'dict' objects} 1 0.000 0.000 0.000 0.000 {method 'copy' of 'dict' objects} 3 0.000 0.000 0.000 0.000 {thread.get_ident} 1 0.000 0.000 0.000 0.000 __init__.py:172(c_ushort) 1 0.000 0.000 0.000 0.000 __init__.py:205(c_longdouble) 1 0.000 0.000 0.000 0.000 __init__.py:243(c_char_p) 1 0.000 0.000 0.000 0.000 ImageEnhance.py:40(Color) 1 0.000 0.000 0.000 0.000 __init__.py:14(<module>) 1 0.000 0.000 0.000 0.000 ImageFilter.py:198(DETAIL) 1 0.000 0.000 0.000 0.000 optparse.py:960(set_conflict_handler) 1 0.000 0.000 0.000 0.000 numbers.py:13(Number) 1 0.000 0.000 0.000 0.000 threading.py:1008(daemon) 1 0.000 0.000 0.000 0.000 ImageFilter.py:225(EMBOSS) 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_sha256} 1 0.000 0.000 0.000 0.000 threading.py:514(_BoundedSemaphore) 1 0.000 0.000 0.000 0.000 {_ctypes.set_conversion_mode} 1 0.000 0.000 0.000 0.000 ImageFilter.py:25(Kernel) 1 0.000 0.000 0.000 0.000 threading.py:1088(_MainThread) 1 0.000 0.000 0.000 0.000 ImageFilter.py:85(MedianFilter) 1 0.000 0.000 0.000 0.000 threading.py:56(_Verbose) 1 0.000 0.000 0.000 0.000 __init__.py:197(c_float) 1 0.000 0.000 0.000 0.000 __init__.py:332(CDLL) 1 0.000 0.000 0.000 0.000 random.py:650(WichmannHill) 1 0.000 0.000 0.000 0.000 threading.py:1097(_set_daemon) 1 0.000 0.000 0.000 0.000 ImageFilter.py:21(Filter) 1 0.000 0.000 0.000 0.000 optparse.py:1313(_get_all_options) 1 0.000 0.000 0.000 0.000 __future__.py:74(_Feature) 1 0.000 0.000 0.000 0.000 ImageEnhance.py:24(_Enhance) 2 0.000 0.000 0.000 0.000 __init__.py:429(__init__) 1 0.000 0.000 0.000 0.000 optparse.py:1407(check_values) 1 0.000 0.000 0.000 0.000 ImageFilter.py:207(EDGE_ENHANCE) 1 0.000 0.000 0.000 0.000 ImageFilter.py:178(BLUR) 3 0.000 0.000 0.000 0.000 sre_parse.py:90(__init__) 1 0.000 0.000 0.000 0.000 ImageFont.py:166(TransposedFont) 1 0.000 0.000 0.000 0.000 ImageFilter.py:234(FIND_EDGES) 1 0.000 0.000 0.000 0.000 stat.py:55(S_ISLNK) 1 0.000 0.000 0.000 0.000 __init__.py:168(c_short) 1 0.000 0.000 0.000 0.000 ImageEnhance.py:53(Contrast) 2 0.000 0.000 0.000 0.000 UserDict.py:70(__contains__) 1 0.000 0.000 0.000 0.000 ImageFont.py:65(ImageFont) 1 0.000 0.000 0.000 0.000 __init__.py:255(c_void_p) 4 0.000 0.000 0.000 0.000 {method 'remove' of 'set' objects} 1 0.000 0.000 0.000 0.000 _endian.py:49(BigEndianStructure) 1 0.000 0.000 0.000 0.000 threading.py:254(_Condition) 1 0.000 0.000 0.000 0.000 ImageFilter.py:216(EDGE_ENHANCE_MORE) 1 0.000 0.000 0.000 0.000 Image.py:33(_imaging_not_installed) 1 0.000 0.000 0.000 0.000 Image.py:417(_E) 1 0.000 0.000 0.000 0.000 Image.py:1710(_ImageCrop) 1 0.000 0.000 0.000 0.000 ImageFilter.py:99(MinFilter) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 1 0.000 0.000 0.000 0.000 __init__.py:388(PyDLL) 1 0.000 0.000 0.000 0.000 ImageFont.py:39(_imagingft_not_installed) 1 0.000 0.000 0.000 0.000 __init__.py:193(c_uint) 1 0.000 0.000 0.000 0.000 optparse.py:225(set_parser) 1 0.000 0.000 0.000 0.000 __init__.py:233(c_byte) 1 0.000 0.000 0.000 0.000 Image.py:1749(ImageTransformHandler) 1 0.000 0.000 0.000 0.000 __init__.py:180(c_ulong) 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_sha224} 2 0.000 0.000 0.000 0.000 {method 'extend' of 'list' objects} 1 0.000 0.000 0.000 0.000 ImageEnhance.py:78(Sharpness) 1 0.000 0.000 0.000 0.000 threading.py:1128(_DummyThread) 1 0.000 0.000 0.000 0.000 ImageFilter.py:243(SMOOTH) 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_sha1} 1 0.000 0.000 0.000 0.000 optparse.py:756(get_opt_string) 8 0.000 0.000 0.000 0.000 sre_compile.py:24(_identityfunction) 1 0.000 0.000 0.000 0.000 _endian.py:26(_swapped_meta) 1 0.000 0.000 0.000 0.000 ImageFilter.py:62(RankFilter) 4 0.000 0.000 0.000 0.000 {method '__subclasshook__' of 'object' objects} 1 0.000 0.000 0.000 0.000 ImageFilter.py:263(SHARPEN) 1 0.000 0.000 0.000 0.000 ImageFilter.py:252(SMOOTH_MORE) 1 0.000 0.000 0.000 0.000 stat.py:24(S_IFMT) 1 0.000 0.000 0.000 0.000 {max} 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_sha384} 1 0.000 0.000 0.000 0.000 optparse.py:944(_create_option_mappings) 4 0.000 0.000 0.000 0.000 {method '__subclasses__' of 'type' objects} 1 0.000 0.000 0.000 0.000 ImageFilter.py:159(UnsharpMask) 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_sha512} 1 0.000 0.000 0.000 0.000 Image.py:1745(ImagePointHandler) 1 0.000 0.000 0.000 0.000 {method 'insert' of 'list' objects} 1 0.000 0.000 0.000 0.000 __init__.py:176(c_long) 1 0.000 0.000 0.000 0.000 __init__.py:201(c_double) 1 0.000 0.000 0.000 0.000 __init__.py:260(c_bool) 2 0.000 0.000 0.000 0.000 threading.py:569(isSet) 1 0.000 0.000 0.000 0.000 ImageFilter.py:189(CONTOUR) 1 0.000 0.000 0.000 0.000 optparse.py:965(set_description) 3 0.000 0.000 0.000 0.000 {method 'release' of 'thread.lock' objects} 1 0.000 0.000 0.000 0.000 {method 'rstrip' of 'str' objects} 1 0.000 0.000 0.000 0.000 __init__.py:226(c_ubyte) 1 0.000 0.000 0.000 0.000 optparse.py:1362(_get_args) 1 0.000 0.000 0.000 0.000 __init__.py:428(LibraryLoader) 1 0.000 0.000 0.000 0.000 __init__.py:159(py_object) real 0m16.480s user 0m16.140s sys 0m0.272s reedy@terbium:~$
And for 1000...
reedy@terbium:~$ time python -m cProfile -s cumtime 'captcha-old.py' --key 'CHANGE_THIS_SECRET!' --output '/tmp/mw-fancycaptcha-1486771866-0b4ca9' --count '1000' --dirs '0' --wordlist '/etc/fancycaptcha/words' --font '/usr/share/fonts/truetype/freefont/FreeMonoBoldOblique.ttf' --blacklist '/etc/fancycaptcha/badwords' Generating 1000 CAPTCHA images separated in 1000 image(s) per chunk run by 1 threads... 308827 function calls (308826 primitive calls) in 185.216 seconds Ordered by: cumulative time ncalls tottime percall cumtime percall filename:lineno(function) 1 0.041 0.041 185.216 185.216 captcha-old.py:28(<module>) 1817 185.074 0.102 185.074 0.102 {time.sleep} 2 0.033 0.017 0.061 0.031 captcha-old.py:175(read_wordlist) 1818 0.020 0.000 0.021 0.000 threading.py:1167(activeCount) 100052 0.013 0.000 0.013 0.000 {method 'lower' of 'str' objects} 100048 0.009 0.000 0.009 0.000 {method 'strip' of 'str' objects} 102953 0.007 0.000 0.007 0.000 {len} 2 0.007 0.003 0.007 0.003 {method 'readlines' of 'file' objects} 1 0.001 0.001 0.005 0.005 Image.py:1(<module>) 1 0.001 0.001 0.004 0.004 Image.py:27(<module>) 1 0.000 0.000 0.002 0.002 {__import__} 1 0.000 0.000 0.002 0.002 FixTk.py:1(<module>) 1 0.000 0.000 0.002 0.002 threading.py:726(start) 1 0.001 0.001 0.002 0.002 __init__.py:4(<module>) 1 0.000 0.000 0.002 0.002 threading.py:602(wait) 1 0.000 0.000 0.002 0.002 threading.py:308(wait) 7 0.002 0.000 0.002 0.000 {method 'acquire' of 'thread.lock' objects} 1 0.001 0.001 0.001 0.001 threading.py:1(<module>) 1 0.000 0.000 0.001 0.001 random.py:40(<module>) 1 0.000 0.000 0.001 0.001 ImageEnhance.py:1(<module>) 1 0.000 0.000 0.001 0.001 ImageEnhance.py:21(<module>) 1 0.000 0.000 0.001 0.001 numbers.py:6(<module>) 1 0.001 0.001 0.001 0.001 hashlib.py:55(<module>) 1 0.000 0.000 0.000 0.000 ImageFont.py:1(<module>) 1 0.000 0.000 0.000 0.000 ImageFilter.py:18(<module>) 16 0.000 0.000 0.000 0.000 optparse.py:1008(add_option) 1 0.000 0.000 0.000 0.000 collections.py:1(<module>) 1 0.000 0.000 0.000 0.000 optparse.py:1191(__init__) 3 0.000 0.000 0.000 0.000 re.py:188(compile) 3 0.000 0.000 0.000 0.000 re.py:226(_compile) 5 0.000 0.000 0.000 0.000 abc.py:86(__new__) 3 0.000 0.000 0.000 0.000 sre_compile.py:493(compile) 1 0.000 0.000 0.000 0.000 ImageFont.py:28(<module>) 16 0.000 0.000 0.000 0.000 optparse.py:561(__init__) 2 0.000 0.000 0.000 0.000 gettext.py:580(gettext) 2 0.000 0.000 0.000 0.000 gettext.py:542(dgettext) 2 0.000 0.000 0.000 0.000 gettext.py:476(translation) 2 0.000 0.000 0.000 0.000 gettext.py:421(find) 1 0.000 0.000 0.000 0.000 warnings.py:45(filterwarnings) 1 0.000 0.000 0.000 0.000 ImageDraw.py:1(<module>) 1 0.000 0.000 0.000 0.000 __init__.py:265(_reset_cache) 1 0.000 0.000 0.000 0.000 optparse.py:1258(_populate_option_list) 1 0.000 0.000 0.000 0.000 optparse.py:1248(_add_help_option) 1 0.000 0.000 0.000 0.000 optparse.py:1277(set_usage) 3 0.000 0.000 0.000 0.000 sre_compile.py:478(_code) 3 0.000 0.000 0.000 0.000 sre_parse.py:675(parse) 2 0.000 0.000 0.000 0.000 threading.py:656(__init__) 1 0.000 0.000 0.000 0.000 ImageDraw.py:33(<module>) 1 0.000 0.000 0.000 0.000 optparse.py:1368(parse_args) 3 0.000 0.000 0.000 0.000 sre_parse.py:301(_parse_sub) 1 0.000 0.000 0.000 0.000 heapq.py:31(<module>) 1 0.000 0.000 0.000 0.000 ImageOps.py:1(<module>) 3 0.000 0.000 0.000 0.000 sre_parse.py:379(_parse) 23 0.000 0.000 0.000 0.000 genericpath.py:15(exists) 4 0.000 0.000 0.000 0.000 abc.py:105(register) 14 0.000 0.000 0.000 0.000 __init__.py:147(_check_size) 16 0.000 0.000 0.000 0.000 optparse.py:610(_set_attrs) 5 0.000 0.000 0.000 0.000 {built-in method __new__ of type object at 0x91d400} 3 0.000 0.000 0.000 0.000 sre_compile.py:359(_compile_info) 10/9 0.000 0.000 0.000 0.000 {issubclass} 25 0.000 0.000 0.000 0.000 posixpath.py:68(join) 3 0.000 0.000 0.000 0.000 __init__.py:78(CFUNCTYPE) 4 0.000 0.000 0.000 0.000 abc.py:148(__subclasscheck__) 1 0.000 0.000 0.000 0.000 optparse.py:1420(_process_args) 6 0.000 0.000 0.000 0.000 gettext.py:130(_expand_lang) 2 0.000 0.000 0.000 0.000 sre_compile.py:178(_compile_charset) 7 0.000 0.000 0.000 0.000 optparse.py:1480(_process_long_opt) 215 0.000 0.000 0.000 0.000 {getattr} 1 0.000 0.000 0.000 0.000 threading.py:1090(__init__) 23 0.000 0.000 0.000 0.000 {posix.stat} 2 0.000 0.000 0.000 0.000 sre_compile.py:207(_optimize_charset) 1 0.000 0.000 0.000 0.000 _endian.py:4(<module>) 3 0.000 0.000 0.000 0.000 sre_compile.py:32(_compile) 46 0.000 0.000 0.000 0.000 abc.py:89(<genexpr>) 2 0.000 0.000 0.000 0.000 threading.py:541(Event) 4 0.000 0.000 0.000 0.000 threading.py:241(Condition) 1 0.000 0.000 0.000 0.000 random.py:91(__init__) 3 0.000 0.000 0.000 0.000 __init__.py:493(PYFUNCTYPE) 1 0.000 0.000 0.000 0.000 random.py:100(seed) 2 0.000 0.000 0.000 0.000 threading.py:560(__init__) 4 0.000 0.000 0.000 0.000 threading.py:259(__init__) 32 0.000 0.000 0.000 0.000 sre_parse.py:201(get) 1 0.000 0.000 0.000 0.000 ImageStat.py:24(<module>) 2 0.000 0.000 0.000 0.000 {_ctypes.POINTER} 1 0.000 0.000 0.000 0.000 {thread.start_new_thread} 1 0.000 0.000 0.000 0.000 optparse.py:1319(get_default_values) 37 0.000 0.000 0.000 0.000 sre_parse.py:182(__next) 16 0.000 0.000 0.000 0.000 optparse.py:589(_set_opt_strings) 1 0.000 0.000 0.000 0.000 posixpath.py:379(realpath) 7 0.000 0.000 0.000 0.000 optparse.py:779(process) 1 0.000 0.000 0.000 0.000 __init__.py:349(__init__) 16 0.000 0.000 0.000 0.000 optparse.py:636(_check_type) 2 0.000 0.000 0.000 0.000 posixpath.py:365(abspath) 5 0.000 0.000 0.000 0.000 _weakrefset.py:58(__iter__) 1 0.000 0.000 0.000 0.000 ImageColor.py:20(<module>) 16 0.000 0.000 0.000 0.000 _weakrefset.py:36(__init__) 214 0.000 0.000 0.000 0.000 {setattr} 16 0.000 0.000 0.000 0.000 optparse.py:679(_check_dest) 1 0.000 0.000 0.000 0.000 _util.py:1(<module>) 185 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects} 7 0.000 0.000 0.000 0.000 optparse.py:772(convert_value) 2 0.000 0.000 0.000 0.000 posixpath.py:336(normpath) 68 0.000 0.000 0.000 0.000 {method 'add' of 'set' objects} 74 0.000 0.000 0.000 0.000 {method 'startswith' of 'str' objects} 1 0.000 0.000 0.000 0.000 posixpath.py:387(_joinrealpath) 8 0.000 0.000 0.000 0.000 optparse.py:765(check_value) 1 0.000 0.000 0.000 0.000 numbers.py:34(Complex) 18 0.000 0.000 0.000 0.000 {_struct.calcsize} 1 0.000 0.000 0.000 0.000 {posix.urandom} 42 0.000 0.000 0.000 0.000 {isinstance} 6 0.000 0.000 0.000 0.000 locale.py:363(normalize) 6 0.000 0.000 0.000 0.000 hashlib.py:94(__get_openssl_constructor) 3 0.000 0.000 0.000 0.000 sre_parse.py:140(getwidth) 1 0.000 0.000 0.000 0.000 threading.py:640(Thread) 16 0.000 0.000 0.000 0.000 optparse.py:580(_check_opt_strings) 1 0.000 0.000 0.000 0.000 {function seed at 0x7f2f2e9f4ed8} 1 0.000 0.000 0.000 0.000 ImageOps.py:20(<module>) 2 0.000 0.000 0.000 0.000 {method 'close' of 'file' objects} 2 0.000 0.000 0.000 0.000 {open} 1 0.000 0.000 0.000 0.000 __future__.py:48(<module>) 1 0.000 0.000 0.000 0.000 optparse.py:366(__init__) 1 0.000 0.000 0.000 0.000 threading.py:575(set) 16 0.000 0.000 0.000 0.000 optparse.py:981(_check_conflict) 1 0.000 0.000 0.000 0.000 {math.exp} 1 0.000 0.000 0.000 0.000 threading.py:709(_set_daemon) 37 0.000 0.000 0.000 0.000 abc.py:15(abstractmethod) 1 0.000 0.000 0.000 0.000 threading.py:296(_acquire_restore) 10 0.000 0.000 0.000 0.000 {hasattr} 1 0.000 0.000 0.000 0.000 numbers.py:295(Integral) 1 0.000 0.000 0.000 0.000 optparse.py:200(__init__) 23 0.000 0.000 0.000 0.000 sre_parse.py:138(append) 1 0.000 0.000 0.000 0.000 Image.py:447(Image) 3 0.000 0.000 0.000 0.000 sre_parse.py:178(__init__) 4 0.000 0.000 0.000 0.000 _weakrefset.py:26(__exit__) 66 0.000 0.000 0.000 0.000 {method 'endswith' of 'str' objects} 8 0.000 0.000 0.000 0.000 _weakrefset.py:83(add) 9 0.000 0.000 0.000 0.000 {range} 1 0.000 0.000 0.000 0.000 optparse.py:838(__init__) 16 0.000 0.000 0.000 0.000 optparse.py:833(isbasestring) 2 0.000 0.000 0.000 0.000 optparse.py:424(check_builtin) 2 0.000 0.000 0.000 0.000 optparse.py:413(_parse_int) 1 0.000 0.000 0.000 0.000 posixpath.py:139(islink) 8 0.000 0.000 0.000 0.000 threading.py:58(__init__) 1 0.000 0.000 0.000 0.000 collections.py:26(OrderedDict) 1 0.000 0.000 0.000 0.000 threading.py:399(notifyAll) 7 0.000 0.000 0.000 0.000 optparse.py:1471(_match_long_opt) 15 0.000 0.000 0.000 0.000 {method 'pop' of 'list' objects} 37 0.000 0.000 0.000 0.000 {method 'get' of 'dict' objects} 9 0.000 0.000 0.000 0.000 {method 'items' of 'dict' objects} 1 0.000 0.000 0.000 0.000 random.py:72(Random) 6 0.000 0.000 0.000 0.000 sre_compile.py:472(isstring) 16 0.000 0.000 0.000 0.000 optparse.py:694(_check_const) 15 0.000 0.000 0.000 0.000 {method 'replace' of 'str' objects} 2 0.000 0.000 0.000 0.000 optparse.py:400(_parse_num) 1 0.000 0.000 0.000 0.000 numbers.py:169(Real) 1 0.000 0.000 0.000 0.000 posixpath.py:127(dirname) 1 0.000 0.000 0.000 0.000 keyword.py:11(<module>) 1 0.000 0.000 0.000 0.000 numbers.py:270(Rational) 3 0.000 0.000 0.000 0.000 {_sre.compile} 7 0.000 0.000 0.000 0.000 optparse.py:791(take_action) 1 0.000 0.000 0.000 0.000 optparse.py:933(__init__) 1 0.000 0.000 0.000 0.000 threading.py:372(notify) 2 0.000 0.000 0.000 0.000 {math.log} 2 0.000 0.000 0.000 0.000 UserDict.py:58(get) 1 0.000 0.000 0.000 0.000 threading.py:627(_newname) 3 0.000 0.000 0.000 0.000 sre_parse.py:67(__init__) 1 0.000 0.000 0.000 0.000 threading.py:1152(currentThread) 1 0.000 0.000 0.000 0.000 ImageDraw.py:49(ImageDraw) 4 0.000 0.000 0.000 0.000 _weakrefset.py:20(__enter__) 18 0.000 0.000 0.000 0.000 {method 'find' of 'str' objects} 16 0.000 0.000 0.000 0.000 optparse.py:700(_check_nargs) 7 0.000 0.000 0.000 0.000 _weakrefset.py:70(__contains__) 1 0.000 0.000 0.000 0.000 threading.py:1035(setDaemon) 3 0.000 0.000 0.000 0.000 UserDict.py:18(__getitem__) 16 0.000 0.000 0.000 0.000 {filter} 6 0.000 0.000 0.000 0.000 {thread.allocate_lock} 1 0.000 0.000 0.000 0.000 ImageMode.py:17(<module>) 1 0.000 0.000 0.000 0.000 {posix.lstat} 4 0.000 0.000 0.000 0.000 {method 'split' of 'str' objects} 1 0.000 0.000 0.000 0.000 threading.py:422(_Semaphore) 1 0.000 0.000 0.000 0.000 _binary.py:14(<module>) 1 0.000 0.000 0.000 0.000 {_ctypes.dlopen} 5 0.000 0.000 0.000 0.000 sre_parse.py:195(match) 7 0.000 0.000 0.000 0.000 {min} 16 0.000 0.000 0.000 0.000 optparse.py:666(_check_choice) 16 0.000 0.000 0.000 0.000 optparse.py:630(_check_action) 16 0.000 0.000 0.000 0.000 optparse.py:709(_check_callback) 38 0.000 0.000 0.000 0.000 {_ctypes.sizeof} 3 0.000 0.000 0.000 0.000 threading.py:63(_note) 1 0.000 0.000 0.000 0.000 {binascii.hexlify} 2 0.000 0.000 0.000 0.000 threading.py:299(_is_owned) 1 0.000 0.000 0.000 0.000 threading.py:1024(daemon) 1 0.000 0.000 0.000 0.000 ImageFont.py:120(FreeTypeFont) 1 0.000 0.000 0.000 0.000 ImageFilter.py:113(MaxFilter) 1 0.000 0.000 0.000 0.000 {sorted} 1 0.000 0.000 0.000 0.000 threading.py:254(_Condition) 1 0.000 0.000 0.000 0.000 collections.py:387(Counter) 7 0.000 0.000 0.000 0.000 __future__.py:75(__init__) 1 0.000 0.000 0.000 0.000 {math.sqrt} 1 0.000 0.000 0.000 0.000 optparse.py:1243(_create_option_list) 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_md5} 1 0.000 0.000 0.000 0.000 {posix.getcwd} 1 0.000 0.000 0.000 0.000 random.py:800(SystemRandom) 8 0.000 0.000 0.000 0.000 sre_compile.py:24(_identityfunction) 23 0.000 0.000 0.000 0.000 {ord} 4 0.000 0.000 0.000 0.000 _weakrefset.py:52(_commit_removals) 1 0.000 0.000 0.000 0.000 __init__.py:14(<module>) 1 0.000 0.000 0.000 0.000 {_ctypes.set_conversion_mode} 2 0.000 0.000 0.000 0.000 {method 'setter' of 'property' objects} 1 0.000 0.000 0.000 0.000 __init__.py:332(CDLL) 3 0.000 0.000 0.000 0.000 __init__.py:494(CFunctionType) 1 0.000 0.000 0.000 0.000 threading.py:124(_RLock) 1 0.000 0.000 0.000 0.000 random.py:650(WichmannHill) 3 0.000 0.000 0.000 0.000 posixpath.py:59(isabs) 6 0.000 0.000 0.000 0.000 {method 'translate' of 'str' objects} 1 0.000 0.000 0.000 0.000 optparse.py:1362(_get_args) 1 0.000 0.000 0.000 0.000 ImageStat.py:29(Stat) 6 0.000 0.000 0.000 0.000 {method 'pop' of 'dict' objects} 1 0.000 0.000 0.000 0.000 threading.py:1058(_Timer) 7 0.000 0.000 0.000 0.000 optparse.py:1675(_match_abbrev) 1 0.000 0.000 0.000 0.000 threading.py:293(_release_save) 1 0.000 0.000 0.000 0.000 optparse.py:225(set_parser) 1 0.000 0.000 0.000 0.000 threading.py:551(_Event) 1 0.000 0.000 0.000 0.000 threading.py:789(_set_ident) 1 0.000 0.000 0.000 0.000 ImageEnhance.py:66(Brightness) 1 0.000 0.000 0.000 0.000 ImageFilter.py:127(ModeFilter) 1 0.000 0.000 0.000 0.000 {method 'rfind' of 'str' objects} 1 0.000 0.000 0.000 0.000 __init__.py:233(c_byte) 1 0.000 0.000 0.000 0.000 __init__.py:359(_FuncPtr) 7 0.000 0.000 0.000 0.000 optparse.py:753(takes_value) 2 0.000 0.000 0.000 0.000 {method 'extend' of 'list' objects} 1 0.000 0.000 0.000 0.000 ImageEnhance.py:78(Sharpness) 1 0.000 0.000 0.000 0.000 ImageFilter.py:243(SMOOTH) 1 0.000 0.000 0.000 0.000 optparse.py:1268(_init_parsing_state) 1 0.000 0.000 0.000 0.000 ImageMode.py:22(ModeDescriptor) 6 0.000 0.000 0.000 0.000 {globals} 1 0.000 0.000 0.000 0.000 _endian.py:26(_swapped_meta) 1 0.000 0.000 0.000 0.000 {method 'keys' of 'dict' objects} 1 0.000 0.000 0.000 0.000 {method 'copy' of 'dict' objects} 3 0.000 0.000 0.000 0.000 {thread.get_ident} 1 0.000 0.000 0.000 0.000 ImageFilter.py:62(RankFilter) 1 0.000 0.000 0.000 0.000 __init__.py:243(c_char_p) 1 0.000 0.000 0.000 0.000 ImageFilter.py:198(DETAIL) 1 0.000 0.000 0.000 0.000 optparse.py:960(set_conflict_handler) 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_sha384} 1 0.000 0.000 0.000 0.000 numbers.py:13(Number) 1 0.000 0.000 0.000 0.000 threading.py:1008(daemon) 1 0.000 0.000 0.000 0.000 optparse.py:944(_create_option_mappings) 1 0.000 0.000 0.000 0.000 ImageFilter.py:225(EMBOSS) 4 0.000 0.000 0.000 0.000 {method '__subclasses__' of 'type' objects} 1 0.000 0.000 0.000 0.000 threading.py:514(_BoundedSemaphore) 1 0.000 0.000 0.000 0.000 ImageFilter.py:159(UnsharpMask) 1 0.000 0.000 0.000 0.000 ImageFilter.py:25(Kernel) 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_sha512} 2 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects} 1 0.000 0.000 0.000 0.000 ImageFilter.py:85(MedianFilter) 1 0.000 0.000 0.000 0.000 threading.py:56(_Verbose) 1 0.000 0.000 0.000 0.000 __init__.py:197(c_float) 1 0.000 0.000 0.000 0.000 {method 'insert' of 'list' objects} 4 0.000 0.000 0.000 0.000 _weakrefset.py:16(__init__) 1 0.000 0.000 0.000 0.000 __init__.py:201(c_double) 12 0.000 0.000 0.000 0.000 {_sre.getlower} 1 0.000 0.000 0.000 0.000 ImageFilter.py:21(Filter) 1 0.000 0.000 0.000 0.000 optparse.py:1313(_get_all_options) 1 0.000 0.000 0.000 0.000 __future__.py:74(_Feature) 1 0.000 0.000 0.000 0.000 ImageEnhance.py:24(_Enhance) 2 0.000 0.000 0.000 0.000 __init__.py:429(__init__) 1 0.000 0.000 0.000 0.000 ImageFilter.py:207(EDGE_ENHANCE) 3 0.000 0.000 0.000 0.000 {method 'release' of 'thread.lock' objects} 3 0.000 0.000 0.000 0.000 sre_parse.py:90(__init__) 1 0.000 0.000 0.000 0.000 ImageFont.py:166(TransposedFont) 1 0.000 0.000 0.000 0.000 stat.py:55(S_ISLNK) 2 0.000 0.000 0.000 0.000 UserDict.py:70(__contains__) 1 0.000 0.000 0.000 0.000 ImageFont.py:65(ImageFont) 1 0.000 0.000 0.000 0.000 {method 'rstrip' of 'str' objects} 4 0.000 0.000 0.000 0.000 {method 'remove' of 'set' objects} 1 0.000 0.000 0.000 0.000 _endian.py:49(BigEndianStructure) 1 0.000 0.000 0.000 0.000 ImageFilter.py:263(SHARPEN) 3 0.000 0.000 0.000 0.000 __init__.py:104(CFunctionType) 1 0.000 0.000 0.000 0.000 ImageFilter.py:216(EDGE_ENHANCE_MORE) 1 0.000 0.000 0.000 0.000 Image.py:417(_E) 1 0.000 0.000 0.000 0.000 ImageEnhance.py:40(Color) 1 0.000 0.000 0.000 0.000 __init__.py:428(LibraryLoader) 1 0.000 0.000 0.000 0.000 __init__.py:159(py_object) 1 0.000 0.000 0.000 0.000 __init__.py:388(PyDLL) 1 0.000 0.000 0.000 0.000 ImageFont.py:39(_imagingft_not_installed) 6 0.000 0.000 0.000 0.000 {method 'reverse' of 'list' objects} 1 0.000 0.000 0.000 0.000 __init__.py:193(c_uint) 1 0.000 0.000 0.000 0.000 __init__.py:294(c_wchar) 1 0.000 0.000 0.000 0.000 {method 'partition' of 'str' objects} 1 0.000 0.000 0.000 0.000 ImageFilter.py:145(GaussianBlur) 1 0.000 0.000 0.000 0.000 Image.py:1749(ImageTransformHandler) 1 0.000 0.000 0.000 0.000 __init__.py:180(c_ulong) 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_sha224} 1 0.000 0.000 0.000 0.000 ImageFilter.py:57(BuiltinFilter) 1 0.000 0.000 0.000 0.000 __init__.py:189(c_int) 1 0.000 0.000 0.000 0.000 threading.py:1128(_DummyThread) 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_sha1} 1 0.000 0.000 0.000 0.000 optparse.py:756(get_opt_string) 1 0.000 0.000 0.000 0.000 __init__.py:291(c_wchar_p) 1 0.000 0.000 0.000 0.000 __init__.py:238(c_char) 2 0.000 0.000 0.000 0.000 {method 'clear' of 'dict' objects} 1 0.000 0.000 0.000 0.000 __init__.py:172(c_ushort) 1 0.000 0.000 0.000 0.000 __init__.py:205(c_longdouble) 4 0.000 0.000 0.000 0.000 {method '__subclasshook__' of 'object' objects} 1 0.000 0.000 0.000 0.000 ImageFilter.py:252(SMOOTH_MORE) 1 0.000 0.000 0.000 0.000 stat.py:24(S_IFMT) 1 0.000 0.000 0.000 0.000 {max} 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_sha256} 1 0.000 0.000 0.000 0.000 threading.py:1088(_MainThread) 1 0.000 0.000 0.000 0.000 Image.py:1745(ImagePointHandler) 1 0.000 0.000 0.000 0.000 __init__.py:176(c_long) 1 0.000 0.000 0.000 0.000 __init__.py:260(c_bool) 1 0.000 0.000 0.000 0.000 threading.py:1097(_set_daemon) 2 0.000 0.000 0.000 0.000 threading.py:569(isSet) 1 0.000 0.000 0.000 0.000 ImageFilter.py:189(CONTOUR) 1 0.000 0.000 0.000 0.000 optparse.py:965(set_description) 1 0.000 0.000 0.000 0.000 optparse.py:1407(check_values) 1 0.000 0.000 0.000 0.000 ImageFilter.py:178(BLUR) 1 0.000 0.000 0.000 0.000 ImageFilter.py:234(FIND_EDGES) 1 0.000 0.000 0.000 0.000 __init__.py:168(c_short) 1 0.000 0.000 0.000 0.000 ImageEnhance.py:53(Contrast) 1 0.000 0.000 0.000 0.000 __init__.py:255(c_void_p) 1 0.000 0.000 0.000 0.000 __init__.py:226(c_ubyte) 1 0.000 0.000 0.000 0.000 Image.py:33(_imaging_not_installed) 1 0.000 0.000 0.000 0.000 Image.py:1710(_ImageCrop) 1 0.000 0.000 0.000 0.000 ImageFilter.py:99(MinFilter) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} real 3m5.262s user 3m1.194s sys 0m4.044s
And 1000 on 4 threads
reedy@terbium:~$ time python -m cProfile -s cumtime 'captcha-old.py' --key 'CHANGE_THIS_SECRET!' --output '/tmp/mw-fancycaptcha-1486771866-0b4ca9' --count '1000' --dirs '0' --wordlist '/etc/fancycaptcha/words' --font '/usr/share/fonts/truetype/freefont/FreeMonoBoldOblique.ttf' --blacklist '/etc/fancycaptcha/badwords' --threads 4 Generating 1000 CAPTCHA images separated in 250 image(s) per chunk run by 4 threads... 307233 function calls (307232 primitive calls) in 148.558 seconds Ordered by: cumulative time ncalls tottime percall cumtime percall filename:lineno(function) 1 0.069 0.069 148.558 148.558 captcha-old.py:28(<module>) 1384 147.918 0.107 147.918 0.107 {time.sleep} 1385 0.483 0.000 0.484 0.000 threading.py:1167(activeCount) 2 0.033 0.016 0.062 0.031 captcha-old.py:175(read_wordlist) 100054 0.013 0.000 0.013 0.000 {method 'lower' of 'str' objects} 100048 0.009 0.000 0.009 0.000 {method 'strip' of 'str' objects} 102088 0.007 0.000 0.007 0.000 {len} 4 0.000 0.000 0.007 0.002 threading.py:726(start) 4 0.000 0.000 0.007 0.002 threading.py:602(wait) 4 0.000 0.000 0.006 0.002 threading.py:308(wait) 22 0.006 0.000 0.006 0.000 {method 'acquire' of 'thread.lock' objects} 2 0.006 0.003 0.006 0.003 {method 'readlines' of 'file' objects} 1 0.001 0.001 0.005 0.005 Image.py:1(<module>) 1 0.001 0.001 0.004 0.004 Image.py:27(<module>) 5 0.000 0.000 0.003 0.001 threading.py:656(__init__) 4 0.003 0.001 0.003 0.001 threading.py:709(_set_daemon) 1 0.000 0.000 0.002 0.002 {__import__} 1 0.000 0.000 0.002 0.002 FixTk.py:1(<module>) 1 0.001 0.001 0.002 0.002 __init__.py:4(<module>) 1 0.001 0.001 0.001 0.001 threading.py:1(<module>) 1 0.000 0.000 0.001 0.001 random.py:40(<module>) 1 0.000 0.000 0.001 0.001 ImageEnhance.py:1(<module>) 1 0.000 0.000 0.001 0.001 ImageEnhance.py:21(<module>) 1 0.000 0.000 0.001 0.001 numbers.py:6(<module>) 1 0.001 0.001 0.001 0.001 hashlib.py:55(<module>) 1 0.000 0.000 0.000 0.000 ImageFont.py:1(<module>) 1 0.000 0.000 0.000 0.000 ImageFilter.py:18(<module>) 1 0.000 0.000 0.000 0.000 optparse.py:1191(__init__) 16 0.000 0.000 0.000 0.000 optparse.py:1008(add_option) 3 0.000 0.000 0.000 0.000 re.py:188(compile) 3 0.000 0.000 0.000 0.000 re.py:226(_compile) 1 0.000 0.000 0.000 0.000 collections.py:1(<module>) 5 0.000 0.000 0.000 0.000 abc.py:86(__new__) 3 0.000 0.000 0.000 0.000 sre_compile.py:493(compile) 1 0.000 0.000 0.000 0.000 ImageFont.py:28(<module>) 2 0.000 0.000 0.000 0.000 gettext.py:580(gettext) 2 0.000 0.000 0.000 0.000 gettext.py:542(dgettext) 2 0.000 0.000 0.000 0.000 gettext.py:476(translation) 2 0.000 0.000 0.000 0.000 gettext.py:421(find) 16 0.000 0.000 0.000 0.000 optparse.py:561(__init__) 1 0.000 0.000 0.000 0.000 warnings.py:45(filterwarnings) 1 0.000 0.000 0.000 0.000 ImageDraw.py:1(<module>) 1 0.000 0.000 0.000 0.000 __init__.py:265(_reset_cache) 1 0.000 0.000 0.000 0.000 optparse.py:1258(_populate_option_list) 1 0.000 0.000 0.000 0.000 optparse.py:1248(_add_help_option) 1 0.000 0.000 0.000 0.000 optparse.py:1277(set_usage) 3 0.000 0.000 0.000 0.000 sre_compile.py:478(_code) 3 0.000 0.000 0.000 0.000 sre_parse.py:675(parse) 10 0.000 0.000 0.000 0.000 threading.py:241(Condition) 1 0.000 0.000 0.000 0.000 optparse.py:1368(parse_args) 1 0.000 0.000 0.000 0.000 ImageDraw.py:33(<module>) 4 0.000 0.000 0.000 0.000 {thread.start_new_thread} 5 0.000 0.000 0.000 0.000 threading.py:541(Event) 3 0.000 0.000 0.000 0.000 sre_parse.py:301(_parse_sub) 5 0.000 0.000 0.000 0.000 threading.py:560(__init__) 3 0.000 0.000 0.000 0.000 sre_parse.py:379(_parse) 23 0.000 0.000 0.000 0.000 genericpath.py:15(exists) 1 0.000 0.000 0.000 0.000 heapq.py:31(<module>) 1 0.000 0.000 0.000 0.000 ImageOps.py:1(<module>) 10 0.000 0.000 0.000 0.000 threading.py:259(__init__) 14 0.000 0.000 0.000 0.000 __init__.py:147(_check_size) 4 0.000 0.000 0.000 0.000 abc.py:105(register) 3 0.000 0.000 0.000 0.000 sre_compile.py:359(_compile_info) 5 0.000 0.000 0.000 0.000 {built-in method __new__ of type object at 0x91d400} 16 0.000 0.000 0.000 0.000 optparse.py:610(_set_attrs) 1 0.000 0.000 0.000 0.000 optparse.py:1420(_process_args) 25 0.000 0.000 0.000 0.000 posixpath.py:68(join) 10/9 0.000 0.000 0.000 0.000 {issubclass} 3 0.000 0.000 0.000 0.000 __init__.py:78(CFUNCTYPE) 8 0.000 0.000 0.000 0.000 optparse.py:1480(_process_long_opt) 4 0.000 0.000 0.000 0.000 abc.py:148(__subclasscheck__) 2 0.000 0.000 0.000 0.000 sre_compile.py:178(_compile_charset) 6 0.000 0.000 0.000 0.000 gettext.py:130(_expand_lang) 1 0.000 0.000 0.000 0.000 threading.py:1090(__init__) 23 0.000 0.000 0.000 0.000 {posix.stat} 2 0.000 0.000 0.000 0.000 sre_compile.py:207(_optimize_charset) 1 0.000 0.000 0.000 0.000 _endian.py:4(<module>) 3 0.000 0.000 0.000 0.000 sre_compile.py:32(_compile) 4 0.000 0.000 0.000 0.000 threading.py:296(_acquire_restore) 3 0.000 0.000 0.000 0.000 __init__.py:493(PYFUNCTYPE) 215 0.000 0.000 0.000 0.000 {getattr} 46 0.000 0.000 0.000 0.000 abc.py:89(<genexpr>) 1 0.000 0.000 0.000 0.000 random.py:91(__init__) 1 0.000 0.000 0.000 0.000 random.py:100(seed) 32 0.000 0.000 0.000 0.000 sre_parse.py:201(get) 1 0.000 0.000 0.000 0.000 optparse.py:1319(get_default_values) 8 0.000 0.000 0.000 0.000 optparse.py:779(process) 188 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects} 2 0.000 0.000 0.000 0.000 {_ctypes.POINTER} 1 0.000 0.000 0.000 0.000 ImageStat.py:24(<module>) 16 0.000 0.000 0.000 0.000 optparse.py:636(_check_type) 37 0.000 0.000 0.000 0.000 sre_parse.py:182(__next) 1 0.000 0.000 0.000 0.000 posixpath.py:379(realpath) 16 0.000 0.000 0.000 0.000 optparse.py:589(_set_opt_strings) 1 0.000 0.000 0.000 0.000 __init__.py:349(__init__) 2 0.000 0.000 0.000 0.000 posixpath.py:365(abspath) 5 0.000 0.000 0.000 0.000 _weakrefset.py:58(__iter__) 215 0.000 0.000 0.000 0.000 {setattr} 4 0.000 0.000 0.000 0.000 threading.py:627(_newname) 16 0.000 0.000 0.000 0.000 _weakrefset.py:36(__init__) 1 0.000 0.000 0.000 0.000 ImageColor.py:20(<module>) 8 0.000 0.000 0.000 0.000 optparse.py:772(convert_value) 16 0.000 0.000 0.000 0.000 optparse.py:679(_check_dest) 9 0.000 0.000 0.000 0.000 optparse.py:765(check_value) 2 0.000 0.000 0.000 0.000 posixpath.py:336(normpath) 1 0.000 0.000 0.000 0.000 _util.py:1(<module>) 18 0.000 0.000 0.000 0.000 {_struct.calcsize} 6 0.000 0.000 0.000 0.000 locale.py:363(normalize) 3 0.000 0.000 0.000 0.000 sre_parse.py:140(getwidth) 1 0.000 0.000 0.000 0.000 posixpath.py:387(_joinrealpath) 1 0.000 0.000 0.000 0.000 threading.py:640(Thread) 1 0.000 0.000 0.000 0.000 {posix.urandom} 1 0.000 0.000 0.000 0.000 numbers.py:34(Complex) 42 0.000 0.000 0.000 0.000 {isinstance} 20 0.000 0.000 0.000 0.000 threading.py:58(__init__) 2 0.000 0.000 0.000 0.000 {method 'close' of 'file' objects} 6 0.000 0.000 0.000 0.000 hashlib.py:94(__get_openssl_constructor) 37 0.000 0.000 0.000 0.000 abc.py:15(abstractmethod) 1 0.000 0.000 0.000 0.000 ImageOps.py:20(<module>) 74 0.000 0.000 0.000 0.000 {method 'startswith' of 'str' objects} 1 0.000 0.000 0.000 0.000 threading.py:575(set) 4 0.000 0.000 0.000 0.000 threading.py:1152(currentThread) 1 0.000 0.000 0.000 0.000 {function seed at 0x7fc930b57ed8} 1 0.000 0.000 0.000 0.000 __future__.py:48(<module>) 2 0.000 0.000 0.000 0.000 {open} 1 0.000 0.000 0.000 0.000 optparse.py:366(__init__) 16 0.000 0.000 0.000 0.000 optparse.py:580(_check_opt_strings) 68 0.000 0.000 0.000 0.000 {method 'add' of 'set' objects} 23 0.000 0.000 0.000 0.000 sre_parse.py:138(append) 16 0.000 0.000 0.000 0.000 optparse.py:981(_check_conflict) 3 0.000 0.000 0.000 0.000 sre_parse.py:178(__init__) 1 0.000 0.000 0.000 0.000 numbers.py:295(Integral) 1 0.000 0.000 0.000 0.000 optparse.py:200(__init__) 10 0.000 0.000 0.000 0.000 {hasattr} 3 0.000 0.000 0.000 0.000 optparse.py:424(check_builtin) 4 0.000 0.000 0.000 0.000 threading.py:1035(setDaemon) 5 0.000 0.000 0.000 0.000 threading.py:299(_is_owned) 1 0.000 0.000 0.000 0.000 Image.py:447(Image) 1 0.000 0.000 0.000 0.000 {math.exp} 3 0.000 0.000 0.000 0.000 optparse.py:413(_parse_int) 4 0.000 0.000 0.000 0.000 _weakrefset.py:26(__exit__) 9 0.000 0.000 0.000 0.000 {range} 9 0.000 0.000 0.000 0.000 threading.py:63(_note) 1 0.000 0.000 0.000 0.000 threading.py:399(notifyAll) 16 0.000 0.000 0.000 0.000 optparse.py:833(isbasestring) 9 0.000 0.000 0.000 0.000 {method 'items' of 'dict' objects} 1 0.000 0.000 0.000 0.000 posixpath.py:139(islink) 66 0.000 0.000 0.000 0.000 {method 'endswith' of 'str' objects} 1 0.000 0.000 0.000 0.000 optparse.py:838(__init__) 1 0.000 0.000 0.000 0.000 collections.py:26(OrderedDict) 15 0.000 0.000 0.000 0.000 {method 'replace' of 'str' objects} 16 0.000 0.000 0.000 0.000 {filter} 4 0.000 0.000 0.000 0.000 _weakrefset.py:20(__enter__) 8 0.000 0.000 0.000 0.000 _weakrefset.py:83(add) 1 0.000 0.000 0.000 0.000 numbers.py:169(Real) 2 0.000 0.000 0.000 0.000 {math.log} 8 0.000 0.000 0.000 0.000 optparse.py:1471(_match_long_opt) 1 0.000 0.000 0.000 0.000 random.py:72(Random) 1 0.000 0.000 0.000 0.000 threading.py:372(notify) 1 0.000 0.000 0.000 0.000 threading.py:422(_Semaphore) 16 0.000 0.000 0.000 0.000 optparse.py:694(_check_const) 1 0.000 0.000 0.000 0.000 posixpath.py:127(dirname) 1 0.000 0.000 0.000 0.000 keyword.py:11(<module>) 38 0.000 0.000 0.000 0.000 {method 'get' of 'dict' objects} 1 0.000 0.000 0.000 0.000 numbers.py:270(Rational) 16 0.000 0.000 0.000 0.000 optparse.py:630(_check_action) 8 0.000 0.000 0.000 0.000 optparse.py:791(take_action) 3 0.000 0.000 0.000 0.000 optparse.py:400(_parse_num) 1 0.000 0.000 0.000 0.000 optparse.py:933(__init__) 16 0.000 0.000 0.000 0.000 optparse.py:709(_check_callback) 2 0.000 0.000 0.000 0.000 UserDict.py:58(get) 4 0.000 0.000 0.000 0.000 threading.py:1024(daemon) 5 0.000 0.000 0.000 0.000 sre_parse.py:195(match) 1 0.000 0.000 0.000 0.000 ImageDraw.py:49(ImageDraw) 17 0.000 0.000 0.000 0.000 {method 'pop' of 'list' objects} 15 0.000 0.000 0.000 0.000 {thread.allocate_lock} 3 0.000 0.000 0.000 0.000 {_sre.compile} 7 0.000 0.000 0.000 0.000 _weakrefset.py:70(__contains__) 6 0.000 0.000 0.000 0.000 sre_compile.py:472(isstring) 3 0.000 0.000 0.000 0.000 sre_parse.py:67(__init__) 1 0.000 0.000 0.000 0.000 _binary.py:14(<module>) 3 0.000 0.000 0.000 0.000 UserDict.py:18(__getitem__) 1 0.000 0.000 0.000 0.000 ImageMode.py:17(<module>) 16 0.000 0.000 0.000 0.000 optparse.py:700(_check_nargs) 1 0.000 0.000 0.000 0.000 {posix.lstat} 38 0.000 0.000 0.000 0.000 {_ctypes.sizeof} 4 0.000 0.000 0.000 0.000 {method 'split' of 'str' objects} 4 0.000 0.000 0.000 0.000 threading.py:293(_release_save) 1 0.000 0.000 0.000 0.000 {_ctypes.dlopen} 1 0.000 0.000 0.000 0.000 {sorted} 4 0.000 0.000 0.000 0.000 threading.py:1008(daemon) 7 0.000 0.000 0.000 0.000 {min} 18 0.000 0.000 0.000 0.000 {method 'find' of 'str' objects} 16 0.000 0.000 0.000 0.000 optparse.py:666(_check_choice) 1 0.000 0.000 0.000 0.000 collections.py:387(Counter) 1 0.000 0.000 0.000 0.000 {binascii.hexlify} 1 0.000 0.000 0.000 0.000 ImageFont.py:120(FreeTypeFont) 1 0.000 0.000 0.000 0.000 ImageFilter.py:113(MaxFilter) 2 0.000 0.000 0.000 0.000 {method 'setter' of 'property' objects} 3 0.000 0.000 0.000 0.000 __init__.py:494(CFunctionType) 3 0.000 0.000 0.000 0.000 posixpath.py:59(isabs) 1 0.000 0.000 0.000 0.000 {math.sqrt} 1 0.000 0.000 0.000 0.000 ImageStat.py:29(Stat) 1 0.000 0.000 0.000 0.000 optparse.py:1243(_create_option_list) 8 0.000 0.000 0.000 0.000 optparse.py:1675(_match_abbrev) 1 0.000 0.000 0.000 0.000 threading.py:551(_Event) 1 0.000 0.000 0.000 0.000 threading.py:789(_set_ident) 8 0.000 0.000 0.000 0.000 optparse.py:753(takes_value) 2 0.000 0.000 0.000 0.000 {method 'extend' of 'list' objects} 1 0.000 0.000 0.000 0.000 {posix.getcwd} 8 0.000 0.000 0.000 0.000 sre_compile.py:24(_identityfunction) 6 0.000 0.000 0.000 0.000 {thread.get_ident} 4 0.000 0.000 0.000 0.000 _weakrefset.py:52(_commit_removals) 1 0.000 0.000 0.000 0.000 {_ctypes.set_conversion_mode} 1 0.000 0.000 0.000 0.000 __init__.py:332(CDLL) 4 0.000 0.000 0.000 0.000 _weakrefset.py:16(__init__) 1 0.000 0.000 0.000 0.000 threading.py:254(_Condition) 12 0.000 0.000 0.000 0.000 {_sre.getlower} 1 0.000 0.000 0.000 0.000 threading.py:124(_RLock) 1 0.000 0.000 0.000 0.000 random.py:650(WichmannHill) 8 0.000 0.000 0.000 0.000 threading.py:569(isSet) 1 0.000 0.000 0.000 0.000 __future__.py:74(_Feature) 9 0.000 0.000 0.000 0.000 {method 'release' of 'thread.lock' objects} 3 0.000 0.000 0.000 0.000 sre_parse.py:90(__init__) 6 0.000 0.000 0.000 0.000 {method 'translate' of 'str' objects} 7 0.000 0.000 0.000 0.000 __future__.py:75(__init__) 3 0.000 0.000 0.000 0.000 __init__.py:104(CFunctionType) 1 0.000 0.000 0.000 0.000 optparse.py:1362(_get_args) 1 0.000 0.000 0.000 0.000 __init__.py:159(py_object) 1 0.000 0.000 0.000 0.000 __init__.py:193(c_uint) 6 0.000 0.000 0.000 0.000 {method 'pop' of 'dict' objects} 1 0.000 0.000 0.000 0.000 threading.py:1058(_Timer) 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_md5} 1 0.000 0.000 0.000 0.000 ImageFilter.py:145(GaussianBlur) 1 0.000 0.000 0.000 0.000 {method 'rfind' of 'str' objects} 1 0.000 0.000 0.000 0.000 __init__.py:359(_FuncPtr) 1 0.000 0.000 0.000 0.000 __init__.py:180(c_ulong) 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_sha224} 1 0.000 0.000 0.000 0.000 ImageFilter.py:57(BuiltinFilter) 1 0.000 0.000 0.000 0.000 __init__.py:189(c_int) 1 0.000 0.000 0.000 0.000 optparse.py:1268(_init_parsing_state) 1 0.000 0.000 0.000 0.000 __init__.py:238(c_char) 1 0.000 0.000 0.000 0.000 random.py:800(SystemRandom) 1 0.000 0.000 0.000 0.000 {method 'copy' of 'dict' objects} 1 0.000 0.000 0.000 0.000 __init__.py:205(c_longdouble) 1 0.000 0.000 0.000 0.000 ImageFilter.py:62(RankFilter) 1 0.000 0.000 0.000 0.000 __init__.py:243(c_char_p) 1 0.000 0.000 0.000 0.000 __init__.py:14(<module>) 1 0.000 0.000 0.000 0.000 ImageFilter.py:198(DETAIL) 1 0.000 0.000 0.000 0.000 optparse.py:960(set_conflict_handler) 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_sha384} 1 0.000 0.000 0.000 0.000 optparse.py:944(_create_option_mappings) 1 0.000 0.000 0.000 0.000 ImageFilter.py:225(EMBOSS) 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_sha256} 1 0.000 0.000 0.000 0.000 ImageFilter.py:159(UnsharpMask) 1 0.000 0.000 0.000 0.000 ImageFilter.py:25(Kernel) 2 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects} 1 0.000 0.000 0.000 0.000 threading.py:1088(_MainThread) 1 0.000 0.000 0.000 0.000 ImageFilter.py:85(MedianFilter) 1 0.000 0.000 0.000 0.000 threading.py:56(_Verbose) 1 0.000 0.000 0.000 0.000 __init__.py:197(c_float) 1 0.000 0.000 0.000 0.000 {method 'insert' of 'list' objects} 1 0.000 0.000 0.000 0.000 __init__.py:176(c_long) 1 0.000 0.000 0.000 0.000 __init__.py:201(c_double) 1 0.000 0.000 0.000 0.000 threading.py:1097(_set_daemon) 1 0.000 0.000 0.000 0.000 ImageFilter.py:189(CONTOUR) 1 0.000 0.000 0.000 0.000 ImageEnhance.py:24(_Enhance) 1 0.000 0.000 0.000 0.000 ImageFilter.py:207(EDGE_ENHANCE) 1 0.000 0.000 0.000 0.000 ImageFilter.py:178(BLUR) 1 0.000 0.000 0.000 0.000 ImageFont.py:166(TransposedFont) 1 0.000 0.000 0.000 0.000 ImageFilter.py:234(FIND_EDGES) 1 0.000 0.000 0.000 0.000 stat.py:55(S_ISLNK) 1 0.000 0.000 0.000 0.000 __init__.py:168(c_short) 2 0.000 0.000 0.000 0.000 UserDict.py:70(__contains__) 1 0.000 0.000 0.000 0.000 ImageFont.py:65(ImageFont) 1 0.000 0.000 0.000 0.000 __init__.py:255(c_void_p) 4 0.000 0.000 0.000 0.000 {method 'remove' of 'set' objects} 1 0.000 0.000 0.000 0.000 ImageFilter.py:263(SHARPEN) 1 0.000 0.000 0.000 0.000 ImageFilter.py:216(EDGE_ENHANCE_MORE) 1 0.000 0.000 0.000 0.000 Image.py:33(_imaging_not_installed) 1 0.000 0.000 0.000 0.000 Image.py:417(_E) 1 0.000 0.000 0.000 0.000 ImageFilter.py:99(MinFilter) 1 0.000 0.000 0.000 0.000 __init__.py:428(LibraryLoader) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 1 0.000 0.000 0.000 0.000 __init__.py:388(PyDLL) 1 0.000 0.000 0.000 0.000 ImageFont.py:39(_imagingft_not_installed) 6 0.000 0.000 0.000 0.000 {method 'reverse' of 'list' objects} 1 0.000 0.000 0.000 0.000 __init__.py:294(c_wchar) 1 0.000 0.000 0.000 0.000 {method 'partition' of 'str' objects} 1 0.000 0.000 0.000 0.000 optparse.py:225(set_parser) 1 0.000 0.000 0.000 0.000 ImageEnhance.py:66(Brightness) 1 0.000 0.000 0.000 0.000 ImageFilter.py:127(ModeFilter) 1 0.000 0.000 0.000 0.000 __init__.py:233(c_byte) 1 0.000 0.000 0.000 0.000 Image.py:1749(ImageTransformHandler) 1 0.000 0.000 0.000 0.000 ImageEnhance.py:78(Sharpness) 1 0.000 0.000 0.000 0.000 threading.py:1128(_DummyThread) 1 0.000 0.000 0.000 0.000 ImageFilter.py:243(SMOOTH) 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_sha1} 1 0.000 0.000 0.000 0.000 ImageMode.py:22(ModeDescriptor) 1 0.000 0.000 0.000 0.000 optparse.py:756(get_opt_string) 1 0.000 0.000 0.000 0.000 __init__.py:291(c_wchar_p) 6 0.000 0.000 0.000 0.000 {globals} 2 0.000 0.000 0.000 0.000 {method 'clear' of 'dict' objects} 1 0.000 0.000 0.000 0.000 _endian.py:26(_swapped_meta) 1 0.000 0.000 0.000 0.000 {method 'keys' of 'dict' objects} 23 0.000 0.000 0.000 0.000 {ord} 1 0.000 0.000 0.000 0.000 __init__.py:172(c_ushort) 1 0.000 0.000 0.000 0.000 ImageEnhance.py:40(Color) 4 0.000 0.000 0.000 0.000 {method '__subclasshook__' of 'object' objects} 1 0.000 0.000 0.000 0.000 ImageFilter.py:252(SMOOTH_MORE) 1 0.000 0.000 0.000 0.000 stat.py:24(S_IFMT) 1 0.000 0.000 0.000 0.000 {max} 1 0.000 0.000 0.000 0.000 numbers.py:13(Number) 4 0.000 0.000 0.000 0.000 {method '__subclasses__' of 'type' objects} 1 0.000 0.000 0.000 0.000 threading.py:514(_BoundedSemaphore) 1 0.000 0.000 0.000 0.000 {_hashlib.openssl_sha512} 1 0.000 0.000 0.000 0.000 Image.py:1745(ImagePointHandler) 1 0.000 0.000 0.000 0.000 __init__.py:260(c_bool) 1 0.000 0.000 0.000 0.000 ImageFilter.py:21(Filter) 1 0.000 0.000 0.000 0.000 optparse.py:1313(_get_all_options) 1 0.000 0.000 0.000 0.000 optparse.py:965(set_description) 2 0.000 0.000 0.000 0.000 __init__.py:429(__init__) 1 0.000 0.000 0.000 0.000 optparse.py:1407(check_values) 1 0.000 0.000 0.000 0.000 ImageEnhance.py:53(Contrast) 1 0.000 0.000 0.000 0.000 {method 'rstrip' of 'str' objects} 1 0.000 0.000 0.000 0.000 __init__.py:226(c_ubyte) 1 0.000 0.000 0.000 0.000 _endian.py:49(BigEndianStructure) 1 0.000 0.000 0.000 0.000 Image.py:1710(_ImageCrop) real 2m28.609s user 3m59.963s sys 0m22.756s
This method of profiling, used as is... Doesn't give us anything very useful
If we follow https://stackoverflow.com/questions/21274898/python-getting-meaningful-results-from-cprofile and switch to doing it in code... And only in the run_in_thread
1800 7.072 0.004 7.072 0.004 {method 'rotate' of 'ImagingCore' objects} 2700 5.284 0.002 5.284 0.002 {method 'filter' of 'ImagingCore' objects}
seem to be taking most of the time...
1 thread:
reedy@terbium:~$ time python 'captcha-old.py' --key 'CHANGE_THIS_SECRET!' --output '/tmp/mw-fancycaptcha-1486771866-0b4ca9' --count '100' --dirs '0' --wordlist '/etc/fancycaptcha/words' --font '/usr/share/fonts/truetype/freefont/FreeMonoBoldOblique.ttf' --blacklist '/etc/fancycaptcha/badwords' Generating 100 CAPTCHA images separated in 100 image(s) per chunk run by 1 threads... 3721397 function calls (3721379 primitive calls) in 17.073 seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 1800 7.072 0.004 7.072 0.004 {method 'rotate' of 'ImagingCore' objects} 2700 5.284 0.002 5.284 0.002 {method 'filter' of 'ImagingCore' objects} 900 0.943 0.001 0.943 0.001 {PIL._imaging.blend} 149210 0.530 0.000 1.552 0.000 Image.py:1046(paste) 900 0.486 0.001 16.733 0.019 captcha-old.py:52(wobbly_copy) 149310 0.204 0.000 0.204 0.000 {method 'crop' of 'ImagingCore' objects} 2700 0.184 0.000 0.184 0.000 {method 'getband' of 'ImagingCore' objects} 149310 0.181 0.000 0.290 0.000 Image.py:1712(__init__) 149310 0.181 0.000 0.419 0.000 Image.py:1729(load) 448632 0.173 0.000 0.173 0.000 {hasattr} 2700 0.173 0.000 0.173 0.000 {method 'putband' of 'ImagingCore' objects} 307020 0.164 0.000 0.232 0.000 Image.py:628(load) 149310 0.158 0.000 0.571 0.000 Image.py:785(crop) 447630 0.134 0.000 0.307 0.000 Image.py:104(isImageType) 100 0.132 0.001 0.132 0.001 {method 'encode' of 'ImagingEncoder' objects} 157710 0.119 0.000 0.119 0.000 Image.py:461(__init__) 456330 0.102 0.000 0.102 0.000 {method 'pixel_access' of 'ImagingCore' objects} 1000 0.096 0.000 0.096 0.000 {method 'getbbox' of 'ImagingCore' objects} 900 0.085 0.000 0.085 0.000 {PIL._imaging.new} 149210 0.082 0.000 0.082 0.000 {method 'paste' of 'ImagingCore' objects} 151910 0.080 0.000 0.095 0.000 random.py:356(uniform) 1100 0.060 0.000 0.060 0.000 {PIL._imaging.fill} 100 0.058 0.001 17.063 0.171 captcha-old.py:77(gen_captcha) 151742/151741 0.054 0.000 0.058 0.000 {isinstance} 150310 0.049 0.000 0.102 0.000 _util.py:4(isStringType) 149210 0.044 0.000 0.044 0.000 {math.sin} 100 0.043 0.000 0.043 0.000 {method 'render' of 'Font' objects} 7400 0.025 0.000 0.036 0.000 Image.py:472(_new) 200 0.024 0.000 0.024 0.000 {method 'getsize' of 'Font' objects} 152767/152765 0.019 0.000 0.019 0.000 {len} 152276 0.016 0.000 0.016 0.000 {method 'random' of '_random.Random' objects} 900 0.013 0.000 5.784 0.006 Image.py:831(filter) 900 0.010 0.000 0.280 0.000 Image.py:2104(merge) 100 0.007 0.000 0.007 0.000 {method 'draw_bitmap' of 'ImagingDraw' objects} 133 0.006 0.000 0.007 0.000 captcha-old.py:131(try_pick_word) 1800 0.006 0.000 7.089 0.004 Image.py:1338(rotate) 100 0.004 0.000 0.004 0.000 {PIL._imagingft.getfont} 2700 0.004 0.000 5.288 0.002 ImageFilter.py:51(filter) 3001 0.004 0.000 0.004 0.000 {range} 100 0.004 0.000 0.013 0.000 ImageOps.py:353(invert) 1000 0.004 0.000 0.072 0.000 Image.py:1765(new) 1000 0.004 0.000 0.004 0.000 {method 'write' of 'file' objects} 600 0.004 0.000 0.004 0.000 {PIL._imaging.crc32} 900 0.004 0.000 5.788 0.006 ImageEnhance.py:85(__init__) 100 0.003 0.000 0.003 0.000 {method 'point' of 'ImagingCore' objects} 100 0.003 0.000 0.003 0.000 {open} 900 0.002 0.000 0.952 0.001 Image.py:2048(blend) 28371 0.002 0.000 0.002 0.000 {method 'append' of 'list' objects} 1800 0.002 0.000 0.003 0.000 Image.py:300(getmodebands) 900 0.002 0.000 0.003 0.000 abc.py:128(__instancecheck__) 100 0.002 0.000 0.143 0.001 ImageFile.py:435(_save) 100 0.002 0.000 0.150 0.001 PngImagePlugin.py:493(_save) 300 0.001 0.000 0.011 0.000 PngImagePlugin.py:474(putchunk) 3600 0.001 0.000 0.001 0.000 ImageMode.py:36(getmode) 7400 0.001 0.000 0.001 0.000 {method 'copy' of 'dict' objects} 100 0.001 0.000 0.001 0.000 {method 'close' of 'file' objects} 1000 0.001 0.000 0.099 0.000 Image.py:864(getbbox) 910 0.001 0.000 0.001 0.000 _weakrefset.py:70(__contains__) 3200 0.001 0.000 0.002 0.000 _binary.py:18(o8) 900 0.001 0.000 0.953 0.001 ImageEnhance.py:26(enhance) 100 0.001 0.000 0.159 0.002 Image.py:1398(save) 500 0.001 0.000 0.002 0.000 _binary.py:50(o32be) 1800 0.001 0.000 0.001 0.000 Image.py:273(getmodetype) 100 0.001 0.000 0.001 0.000 {method 'flush' of 'file' objects} 366 0.001 0.000 0.001 0.000 random.py:173(randrange) 100 0.001 0.000 0.009 0.000 captcha-old.py:169(pick_word) 100 0.001 0.000 0.002 0.000 ImageDraw.py:293(Draw) 3200 0.001 0.000 0.001 0.000 {chr} 100 0.001 0.000 0.008 0.000 ImageOps.py:44(_lut) 100 0.001 0.000 0.003 0.000 Image.py:316(preinit) 1020 0.001 0.000 0.001 0.000 {getattr} 100 0.000 0.000 0.001 0.000 ImageDraw.py:61(__init__) 600 0.000 0.000 0.001 0.000 _binary.py:47(o16be) 1 0.000 0.000 0.001 0.001 io.py:34(<module>) 100 0.000 0.000 0.007 0.000 Image.py:1130(point) 100 0.000 0.000 0.062 0.001 ImageDraw.py:258(text) 100 0.000 0.000 0.054 0.001 ImageFont.py:151(getmask2) 100 0.000 0.000 0.000 0.000 {_hashlib.openssl_md5} 100 0.000 0.000 0.000 0.000 genericpath.py:85(_splitext) 133 0.000 0.000 0.000 0.000 {method 'search' of '_sre.SRE_Pattern' objects} 100 0.000 0.000 0.000 0.000 {method 'sort' of 'list' objects} 100 0.000 0.000 0.001 0.000 Image.py:394(_getencoder) 100 0.000 0.000 0.000 0.000 posixpath.py:68(join) 100 0.000 0.000 0.005 0.000 ImageFont.py:200(truetype) 266 0.000 0.000 0.001 0.000 random.py:236(randint) 100 0.000 0.000 0.000 0.000 {PIL._imaging.zip_encoder} 300 0.000 0.000 0.000 0.000 _util.py:6(isPath) 1 0.000 0.000 0.001 0.001 BmpImagePlugin.py:27(<module>) 100 0.000 0.000 0.000 0.000 {method 'hexdigest' of '_hashlib.HASH' objects} 100 0.000 0.000 0.005 0.000 ImageFont.py:123(__init__) 200 0.000 0.000 0.000 0.000 {method 'rfind' of 'str' objects} 200 0.000 0.000 0.000 0.000 {max} 100 0.000 0.000 0.014 0.000 ImageFont.py:142(getsize) 100 0.000 0.000 0.000 0.000 ImageDraw.py:137(_getink) 302 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects} 900 0.000 0.000 0.000 0.000 ImageFilter.py:58(__init__) 1 0.000 0.000 0.000 0.000 ascii.py:8(<module>) 100 0.000 0.000 0.000 0.000 Image.py:519(__getattr__) 100 0.000 0.000 0.000 0.000 {method 'setimage' of 'ImagingEncoder' objects} 100 0.000 0.000 0.001 0.000 posixpath.py:104(splitext) 208 0.000 0.000 0.000 0.000 {min} 1 0.000 0.000 0.000 0.000 GifImagePlugin.py:28(<module>) 100 0.000 0.000 0.008 0.000 PngImagePlugin.py:490(write) 1 0.000 0.000 0.001 0.001 ImageFile.py:30(<module>) 614 0.000 0.000 0.000 0.000 {method 'get' of 'dict' objects} 200 0.000 0.000 0.000 0.000 {method 'draw_ink' of 'ImagingDraw' objects} 100 0.000 0.000 0.000 0.000 {method 'startswith' of 'str' objects} 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:34(<module>) 1 0.000 0.000 0.000 0.000 JpegImagePlugin.py:35(<module>) 9 0.000 0.000 0.000 0.000 abc.py:148(__subclasscheck__) 5 0.000 0.000 0.000 0.000 {built-in method __new__ of type object at 0x91d400} 100 0.000 0.000 0.000 0.000 PngImagePlugin.py:487(__init__) 1 0.000 0.000 0.000 0.000 {__import__} 2 0.000 0.000 0.000 0.000 sre_parse.py:379(_parse) 1 0.000 0.000 0.000 0.000 PpmImagePlugin.py:18(<module>) 100 0.000 0.000 0.000 0.000 {PIL._imaging.draw} 100 0.000 0.000 0.000 0.000 {method 'endswith' of 'str' objects} 4 0.000 0.000 0.000 0.000 abc.py:86(__new__) 110 0.000 0.000 0.000 0.000 {method 'lower' of 'str' objects} 4/2 0.000 0.000 0.000 0.000 sre_compile.py:32(_compile) 20 0.000 0.000 0.000 0.000 _weakrefset.py:36(__init__) 100 0.000 0.000 0.000 0.000 ImageFile.py:62(_tilesort) 1 0.000 0.000 0.000 0.000 ImagePalette.py:19(<module>) 123 0.000 0.000 0.000 0.000 {method 'upper' of 'str' objects} 19 0.000 0.000 0.000 0.000 _weakrefset.py:58(__iter__) 6/4 0.000 0.000 0.000 0.000 sre_parse.py:140(getwidth) 100 0.000 0.000 0.000 0.000 {callable} 17 0.000 0.000 0.000 0.000 _weakrefset.py:83(add) 2 0.000 0.000 0.000 0.000 locale.py:363(normalize) 5 0.000 0.000 0.000 0.000 sre_compile.py:178(_compile_charset) 17 0.000 0.000 0.000 0.000 sre_parse.py:182(__next) 2 0.000 0.000 0.000 0.000 sre_compile.py:359(_compile_info) 8 0.000 0.000 0.000 0.000 abc.py:105(register) 27/16 0.000 0.000 0.000 0.000 {issubclass} 2 0.000 0.000 0.000 0.000 re.py:226(_compile) 2 0.000 0.000 0.000 0.000 sre_compile.py:493(compile) 1 0.000 0.000 0.000 0.000 __init__.py:71(search_function) 1 0.000 0.000 0.000 0.000 locale.py:493(getdefaultlocale) 2 0.000 0.000 0.000 0.000 sre_parse.py:675(parse) 5 0.000 0.000 0.000 0.000 Image.py:2131(register_open) 1 0.000 0.000 0.000 0.000 JpegPresets.py:67(<module>) 5 0.000 0.000 0.000 0.000 sre_compile.py:207(_optimize_charset) 12 0.000 0.000 0.000 0.000 sre_parse.py:130(__getitem__) 1 0.000 0.000 0.000 0.000 {method 'encode' of 'unicode' objects} 8 0.000 0.000 0.000 0.000 _weakrefset.py:26(__exit__) 10 0.000 0.000 0.000 0.000 Image.py:2168(register_extension) 15 0.000 0.000 0.000 0.000 sre_parse.py:201(get) 2 0.000 0.000 0.000 0.000 sre_parse.py:301(_parse_sub) 1 0.000 0.000 0.000 0.000 _abcoll.py:24(_hasattr) 4 0.000 0.000 0.000 0.000 {method 'split' of 'str' objects} 8 0.000 0.000 0.000 0.000 _weakrefset.py:20(__enter__) 1 0.000 0.000 0.000 0.000 locale.py:347(_replace_encoding) 8 0.000 0.000 0.000 0.000 _weakrefset.py:52(_commit_removals) 7 0.000 0.000 0.000 0.000 {method 'items' of 'dict' objects} 2 0.000 0.000 0.000 0.000 {_sre.compile} 5 0.000 0.000 0.000 0.000 Image.py:2157(register_save) 2 0.000 0.000 0.000 0.000 __init__.py:49(normalize_encoding) 25 0.000 0.000 0.000 0.000 {method 'add' of 'set' objects} 4 0.000 0.000 0.000 0.000 sre_compile.py:472(isstring) 1 0.000 0.000 0.000 0.000 codecs.py:77(__new__) 4 0.000 0.000 0.000 0.000 abc.py:89(<genexpr>) 16 0.000 0.000 0.000 0.000 ImageMode.py:24(__init__) 1 0.000 0.000 0.000 0.000 {_codecs.utf_8_decode} 1 0.000 0.000 0.000 0.000 ascii.py:41(getregentry) 2 0.000 0.000 0.000 0.000 locale.py:447(_parse_localename) 2 0.000 0.000 0.000 0.000 _abcoll.py:26(<genexpr>) 9 0.000 0.000 0.000 0.000 sre_parse.py:138(append) 1 0.000 0.000 0.000 0.000 _abcoll.py:128(__subclasshook__) 2 0.000 0.000 0.000 0.000 sre_parse.py:178(__init__) 1 0.000 0.000 0.000 0.000 {method 'decode' of 'str' objects} 2 0.000 0.000 0.000 0.000 sre_compile.py:478(_code) 2 0.000 0.000 0.000 0.000 sre_compile.py:354(_simple) 8 0.000 0.000 0.000 0.000 _weakrefset.py:16(__init__) 3 0.000 0.000 0.000 0.000 UserDict.py:70(__contains__) 8 0.000 0.000 0.000 0.000 {method 'remove' of 'set' objects} 3 0.000 0.000 0.000 0.000 UserDict.py:58(get) 1 0.000 0.000 0.000 0.000 {any} 8 0.000 0.000 0.000 0.000 {method '__subclasshook__' of 'object' objects} 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:78(ChunkStream) 2 0.000 0.000 0.000 0.000 re.py:188(compile) 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:179(PngStream) 1 0.000 0.000 0.000 0.000 {_locale.setlocale} 1 0.000 0.000 0.000 0.000 locale.py:546(getlocale) 3 0.000 0.000 0.000 0.000 Image.py:2146(register_mime) 1 0.000 0.000 0.000 0.000 utf_8.py:15(decode) 4 0.000 0.000 0.000 0.000 sre_parse.py:90(__init__) 4 0.000 0.000 0.000 0.000 sre_parse.py:257(_escape) 1 0.000 0.000 0.000 0.000 ImagePalette.py:23(ImagePalette) 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:484(_idat) 2 0.000 0.000 0.000 0.000 sre_parse.py:67(__init__) 1 0.000 0.000 0.000 0.000 ascii.py:13(Codec) 1 0.000 0.000 0.000 0.000 GifImagePlugin.py:53(GifImageFile) 1 0.000 0.000 0.000 0.000 ImageFile.py:268(StubImageFile) 2 0.000 0.000 0.000 0.000 sre_parse.py:134(__setitem__) 3 0.000 0.000 0.000 0.000 {method 'replace' of 'str' objects} 3 0.000 0.000 0.000 0.000 {ord} 1 0.000 0.000 0.000 0.000 UserDict.py:18(__getitem__) 1 0.000 0.000 0.000 0.000 {method 'index' of 'str' objects} 1 0.000 0.000 0.000 0.000 BmpImagePlugin.py:171(DibImageFile) 1 0.000 0.000 0.000 0.000 JpegImagePlugin.py:267(JpegImageFile) 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:341(PngImageFile) 1 0.000 0.000 0.000 0.000 ImageFile.py:298(Parser) 1 0.000 0.000 0.000 0.000 ascii.py:20(IncrementalEncoder) 1 0.000 0.000 0.000 0.000 ImageFile.py:70(ImageFile) 4 0.000 0.000 0.000 0.000 {method 'translate' of 'str' objects} 1 0.000 0.000 0.000 0.000 io.py:69(IOBase) 8 0.000 0.000 0.000 0.000 {method '__subclasses__' of 'type' objects} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 8 0.000 0.000 0.000 0.000 sre_parse.py:126(__len__) 1 0.000 0.000 0.000 0.000 io.py:78(TextIOBase) 1 0.000 0.000 0.000 0.000 BmpImagePlugin.py:59(BmpImageFile) 1 0.000 0.000 0.000 0.000 ascii.py:24(IncrementalDecoder) 4 0.000 0.000 0.000 0.000 sre_parse.py:195(match) 1 0.000 0.000 0.000 0.000 ascii.py:34(StreamConverter) 1 0.000 0.000 0.000 0.000 io.py:75(BufferedIOBase) 1 0.000 0.000 0.000 0.000 PpmImagePlugin.py:56(PpmImageFile) 1 0.000 0.000 0.000 0.000 ascii.py:31(StreamReader) 1 0.000 0.000 0.000 0.000 io.py:72(RawIOBase) 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:154(PngInfo) 1 0.000 0.000 0.000 0.000 ascii.py:28(StreamWriter) real 0m17.277s user 0m16.908s sys 0m0.268s
4 threads:
reedy@terbium:~$ time python 'captcha-old.py' --key 'CHANGE_THIS_SECRET!' --output '/tmp/mw-fancycaptcha-1486771866-0b4ca9' --count '100' --dirs '0' --wordlist '/etc/fancycaptcha/words' --font '/usr/share/fonts/truetype/freefont/FreeMonoBoldOblique.ttf' --blacklist '/etc/fancycaptcha/badwords' --threads 4 Generating 100 CAPTCHA images separated in 25 image(s) per chunk run by 4 threads... 916345 function calls (916344 primitive calls) in 17.555 seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 36751 5.345 0.000 5.345 0.000 {method 'crop' of 'ImagingCore' objects} 450 4.114 0.009 4.114 0.009 {method 'rotate' of 'ImagingCore' objects} 675 2.063 0.003 2.063 0.003 {method 'filter' of 'ImagingCore' objects} 36726 1.528 0.000 1.528 0.000 {method 'paste' of 'ImagingCore' objects} 275 0.845 0.003 0.845 0.003 {PIL._imaging.fill} 225 0.643 0.003 17.142 0.076 captcha-old.py:52(wobbly_copy) 36751 0.443 0.000 5.809 0.000 Image.py:1729(load) 36726 0.392 0.000 7.986 0.000 Image.py:1046(paste) 225 0.390 0.002 0.390 0.002 {PIL._imaging.blend} 36751 0.219 0.000 0.298 0.000 Image.py:1712(__init__) 75602 0.192 0.000 0.217 0.000 Image.py:628(load) 675 0.178 0.000 0.178 0.000 {method 'getband' of 'ImagingCore' objects} 25 0.165 0.007 0.253 0.010 ImageOps.py:353(invert) 38851 0.099 0.000 0.099 0.000 Image.py:461(__init__) 36751 0.085 0.000 0.454 0.000 Image.py:785(crop) 110428 0.080 0.000 0.080 0.000 {hasattr} 225 0.066 0.000 0.066 0.000 {PIL._imaging.new} 110178 0.064 0.000 0.145 0.000 Image.py:104(isImageType) 675 0.063 0.000 0.063 0.000 {method 'putband' of 'ImagingCore' objects} 37401 0.063 0.000 0.070 0.000 random.py:356(uniform) 1850 0.050 0.000 0.070 0.000 Image.py:472(_new) 112353 0.046 0.000 0.046 0.000 {method 'pixel_access' of 'ImagingCore' objects} 25 0.043 0.002 0.043 0.002 {method 'encode' of 'ImagingEncoder' objects} 25 0.040 0.002 0.040 0.002 {method 'point' of 'ImagingCore' objects} 250 0.032 0.000 0.032 0.000 {method 'getbbox' of 'ImagingCore' objects} 450 0.030 0.000 0.043 0.000 Image.py:300(getmodebands) 225 0.030 0.000 0.243 0.001 Image.py:2104(merge) 37001 0.027 0.000 0.049 0.000 _util.py:4(isStringType) 36726 0.025 0.000 0.025 0.000 {math.sin} 37352/37351 0.023 0.000 0.025 0.000 {isinstance} 450 0.020 0.000 4.142 0.009 Image.py:1338(rotate) 25 0.017 0.001 0.017 0.001 {method 'render' of 'Font' objects} 250 0.014 0.000 0.014 0.000 {method 'write' of 'file' objects} 900 0.013 0.000 0.013 0.000 ImageMode.py:36(getmode) 25 0.011 0.000 17.552 0.702 captcha-old.py:77(gen_captcha) 25 0.010 0.000 0.010 0.000 {open} 25 0.009 0.000 0.009 0.000 {method 'flush' of 'file' objects} 50 0.009 0.000 0.009 0.000 {method 'getsize' of 'Font' objects} 37594 0.009 0.000 0.009 0.000 {len} 25 0.009 0.000 0.081 0.003 PngImagePlugin.py:493(_save) 37488 0.007 0.000 0.007 0.000 {method 'random' of '_random.Random' objects} 25 0.007 0.000 0.007 0.000 {method 'draw_bitmap' of 'ImagingDraw' objects} 225 0.006 0.000 2.502 0.011 Image.py:831(filter) 25 0.003 0.000 0.003 0.000 {method 'close' of 'file' objects} 250 0.002 0.000 0.901 0.004 Image.py:1765(new) 31 0.002 0.000 0.002 0.000 captcha-old.py:131(try_pick_word) 675 0.002 0.000 2.064 0.003 ImageFilter.py:51(filter) 25 0.002 0.000 0.002 0.000 {PIL._imagingft.getfont} 751 0.002 0.000 0.002 0.000 {range} 225 0.002 0.000 2.503 0.011 ImageEnhance.py:85(__init__) 75 0.002 0.000 0.016 0.000 PngImagePlugin.py:474(putchunk) 150 0.001 0.000 0.001 0.000 {PIL._imaging.crc32} 25 0.001 0.000 0.053 0.002 ImageFile.py:435(_save) 25 0.001 0.000 0.096 0.004 Image.py:1398(save) 225 0.001 0.000 0.394 0.002 Image.py:2048(blend) 7075 0.001 0.000 0.001 0.000 {method 'append' of 'list' objects} 225 0.001 0.000 0.002 0.000 abc.py:128(__instancecheck__) 250 0.001 0.000 0.035 0.000 Image.py:864(getbbox) 1850 0.001 0.000 0.001 0.000 {method 'copy' of 'dict' objects} 226 0.001 0.000 0.001 0.000 _weakrefset.py:70(__contains__) 225 0.000 0.000 0.394 0.002 ImageEnhance.py:26(enhance) 800 0.000 0.000 0.001 0.000 _binary.py:18(o8) 125 0.000 0.000 0.001 0.000 _binary.py:50(o32be) 450 0.000 0.000 0.001 0.000 Image.py:273(getmodetype) 87 0.000 0.000 0.000 0.000 random.py:173(randrange) 25 0.000 0.000 0.087 0.003 ImageOps.py:44(_lut) 25 0.000 0.000 0.001 0.000 ImageDraw.py:293(Draw) 25 0.000 0.000 0.003 0.000 captcha-old.py:169(pick_word) 250 0.000 0.000 0.000 0.000 {getattr} 800 0.000 0.000 0.000 0.000 {chr} 150 0.000 0.000 0.000 0.000 _binary.py:47(o16be) 25 0.000 0.000 0.087 0.003 Image.py:1130(point) 25 0.000 0.000 0.000 0.000 ImageDraw.py:61(__init__) 25 0.000 0.000 0.030 0.001 ImageDraw.py:258(text) 25 0.000 0.000 0.023 0.001 ImageFont.py:151(getmask2) 25 0.000 0.000 0.000 0.000 {method 'sort' of 'list' objects} 25 0.000 0.000 0.000 0.000 {_hashlib.openssl_md5} 25 0.000 0.000 0.000 0.000 Image.py:394(_getencoder) 25 0.000 0.000 0.000 0.000 ImageDraw.py:137(_getink) 25 0.000 0.000 0.000 0.000 posixpath.py:68(join) 25 0.000 0.000 0.000 0.000 genericpath.py:85(_splitext) 31 0.000 0.000 0.000 0.000 {method 'search' of '_sre.SRE_Pattern' objects} 75 0.000 0.000 0.000 0.000 _util.py:6(isPath) 25 0.000 0.000 0.002 0.000 ImageFont.py:200(truetype) 25 0.000 0.000 0.002 0.000 ImageFont.py:123(__init__) 25 0.000 0.000 0.000 0.000 {PIL._imaging.zip_encoder} 25 0.000 0.000 0.000 0.000 {method 'hexdigest' of '_hashlib.HASH' objects} 50 0.000 0.000 0.000 0.000 {method 'rfind' of 'str' objects} 62 0.000 0.000 0.000 0.000 random.py:236(randint) 25 0.000 0.000 0.005 0.000 ImageFont.py:142(getsize) 225 0.000 0.000 0.000 0.000 ImageFilter.py:58(__init__) 50 0.000 0.000 0.000 0.000 {max} 25 0.000 0.000 0.000 0.000 posixpath.py:104(splitext) 75 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects} 25 0.000 0.000 0.000 0.000 Image.py:519(__getattr__) 50 0.000 0.000 0.000 0.000 {min} 25 0.000 0.000 0.000 0.000 {method 'setimage' of 'ImagingEncoder' objects} 25 0.000 0.000 0.008 0.000 PngImagePlugin.py:490(write) 50 0.000 0.000 0.000 0.000 {method 'draw_ink' of 'ImagingDraw' objects} 25 0.000 0.000 0.000 0.000 PngImagePlugin.py:487(__init__) 25 0.000 0.000 0.000 0.000 {method 'startswith' of 'str' objects} 150 0.000 0.000 0.000 0.000 {method 'get' of 'dict' objects} 25 0.000 0.000 0.000 0.000 Image.py:316(preinit) 25 0.000 0.000 0.000 0.000 {method 'endswith' of 'str' objects} 25 0.000 0.000 0.000 0.000 {callable} 25 0.000 0.000 0.000 0.000 {PIL._imaging.draw} 1 0.000 0.000 0.000 0.000 abc.py:148(__subclasscheck__) 25 0.000 0.000 0.000 0.000 {method 'lower' of 'str' objects} 25 0.000 0.000 0.000 0.000 ImageFile.py:62(_tilesort) 1 0.000 0.000 0.000 0.000 _abcoll.py:24(_hasattr) 1 0.000 0.000 0.000 0.000 _weakrefset.py:36(__init__) 25 0.000 0.000 0.000 0.000 {method 'upper' of 'str' objects} 1 0.000 0.000 0.000 0.000 _weakrefset.py:83(add) 2 0.000 0.000 0.000 0.000 _abcoll.py:26(<genexpr>) 16 0.000 0.000 0.000 0.000 ImageMode.py:24(__init__) 1 0.000 0.000 0.000 0.000 _abcoll.py:128(__subclasshook__) 1 0.000 0.000 0.000 0.000 {method 'items' of 'dict' objects} 1 0.000 0.000 0.000 0.000 {any} 1 0.000 0.000 0.000 0.000 {method 'add' of 'set' objects} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 900231 function calls (900214 primitive calls) in 17.768 seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 36054 5.523 0.000 5.523 0.000 {method 'crop' of 'ImagingCore' objects} 450 3.884 0.009 3.884 0.009 {method 'rotate' of 'ImagingCore' objects} 675 2.047 0.003 2.047 0.003 {method 'filter' of 'ImagingCore' objects} 36029 1.555 0.000 1.555 0.000 {method 'paste' of 'ImagingCore' objects} 275 0.869 0.003 0.869 0.003 {PIL._imaging.fill} 225 0.730 0.003 17.382 0.077 captcha-old.py:52(wobbly_copy) 36029 0.464 0.000 8.258 0.000 Image.py:1046(paste) 36054 0.463 0.000 6.007 0.000 Image.py:1729(load) 225 0.447 0.002 0.447 0.002 {PIL._imaging.blend} 675 0.236 0.000 0.236 0.000 {method 'getband' of 'ImagingCore' objects} 74208 0.199 0.000 0.224 0.000 Image.py:628(load) 38154 0.165 0.000 0.165 0.000 Image.py:461(__init__) 36054 0.163 0.000 0.305 0.000 Image.py:1712(__init__) 25 0.141 0.006 0.210 0.008 ImageOps.py:353(invert) 36054 0.080 0.000 0.459 0.000 Image.py:785(crop) 108339 0.079 0.000 0.079 0.000 {hasattr} 675 0.064 0.000 0.064 0.000 {method 'putband' of 'ImagingCore' objects} 225 0.063 0.000 0.063 0.000 {PIL._imaging.new} 108087 0.054 0.000 0.133 0.000 Image.py:104(isImageType) 25 0.053 0.002 0.053 0.002 {method 'encode' of 'ImagingEncoder' objects} 36704 0.048 0.000 0.056 0.000 random.py:356(uniform) 25 0.047 0.002 0.047 0.002 {method 'point' of 'ImagingCore' objects} 110262 0.046 0.000 0.046 0.000 {method 'pixel_access' of 'ImagingCore' objects} 1850 0.041 0.000 0.064 0.000 Image.py:472(_new) 36304 0.035 0.000 0.058 0.000 _util.py:4(isStringType) 250 0.032 0.000 0.032 0.000 {method 'getbbox' of 'ImagingCore' objects} 250 0.030 0.000 0.030 0.000 {method 'write' of 'file' objects} 225 0.030 0.000 0.229 0.001 Image.py:2104(merge) 36029 0.025 0.000 0.025 0.000 {math.sin} 36685 0.023 0.000 0.025 0.000 {isinstance} 25 0.017 0.001 0.017 0.001 {open} 25 0.015 0.001 0.015 0.001 {method 'render' of 'Font' objects} 250 0.012 0.000 0.060 0.000 Image.py:864(getbbox) 36949/36947 0.009 0.000 0.009 0.000 {len} 50 0.008 0.000 0.008 0.000 {method 'getsize' of 'Font' objects} 25 0.007 0.000 17.765 0.711 captcha-old.py:77(gen_captcha) 36787 0.007 0.000 0.007 0.000 {method 'random' of '_random.Random' objects} 25 0.006 0.000 0.006 0.000 {method 'draw_bitmap' of 'ImagingDraw' objects} 225 0.006 0.000 2.538 0.011 Image.py:831(filter) 450 0.004 0.000 3.922 0.009 Image.py:1338(rotate) 25 0.003 0.000 0.003 0.000 {method 'close' of 'file' objects} 25 0.003 0.000 0.003 0.000 {method 'flush' of 'file' objects} 250 0.002 0.000 0.891 0.004 Image.py:1765(new) 29 0.002 0.000 0.002 0.000 captcha-old.py:131(try_pick_word) 675 0.002 0.000 2.049 0.003 ImageFilter.py:51(filter) 751 0.002 0.000 0.002 0.000 {range} 225 0.002 0.000 2.540 0.011 ImageEnhance.py:85(__init__) 25 0.002 0.000 0.002 0.000 {PIL._imagingft.getfont} 75 0.001 0.000 0.015 0.000 PngImagePlugin.py:474(putchunk) 450 0.001 0.000 0.002 0.000 Image.py:300(getmodebands) 25 0.001 0.000 0.094 0.004 PngImagePlugin.py:493(_save) 150 0.001 0.000 0.001 0.000 {PIL._imaging.crc32} 25 0.001 0.000 0.120 0.005 Image.py:1398(save) 125 0.001 0.000 0.002 0.000 _binary.py:50(o32be) 225 0.001 0.000 0.451 0.002 Image.py:2048(blend) 7146 0.001 0.000 0.001 0.000 {method 'append' of 'list' objects} 25 0.001 0.000 0.060 0.002 ImageFile.py:435(_save) 225 0.001 0.000 0.002 0.000 abc.py:128(__instancecheck__) 800 0.001 0.000 0.001 0.000 _binary.py:18(o8) 25 0.001 0.000 0.004 0.000 Image.py:316(preinit) 900 0.001 0.000 0.001 0.000 ImageMode.py:36(getmode) 1850 0.001 0.000 0.001 0.000 {method 'copy' of 'dict' objects} 1 0.001 0.001 0.001 0.001 io.py:34(<module>) 234 0.001 0.000 0.001 0.000 _weakrefset.py:70(__contains__) 450 0.000 0.000 0.001 0.000 Image.py:273(getmodetype) 225 0.000 0.000 0.451 0.002 ImageEnhance.py:26(enhance) 25 0.000 0.000 0.001 0.000 ImageDraw.py:293(Draw) 25 0.000 0.000 0.068 0.003 ImageOps.py:44(_lut) 83 0.000 0.000 0.000 0.000 random.py:173(randrange) 270 0.000 0.000 0.000 0.000 {getattr} 800 0.000 0.000 0.000 0.000 {chr} 1 0.000 0.000 0.002 0.002 BmpImagePlugin.py:27(<module>) 25 0.000 0.000 0.003 0.000 captcha-old.py:169(pick_word) 25 0.000 0.000 0.067 0.003 Image.py:1130(point) 25 0.000 0.000 0.027 0.001 ImageDraw.py:258(text) 25 0.000 0.000 0.000 0.000 ImageDraw.py:61(__init__) 150 0.000 0.000 0.000 0.000 _binary.py:47(o16be) 1 0.000 0.000 0.000 0.000 GifImagePlugin.py:28(<module>) 25 0.000 0.000 0.000 0.000 {method 'sort' of 'list' objects} 1 0.000 0.000 0.001 0.001 ImageFile.py:30(<module>) 25 0.000 0.000 0.021 0.001 ImageFont.py:151(getmask2) 25 0.000 0.000 0.000 0.000 genericpath.py:85(_splitext) 25 0.000 0.000 0.000 0.000 {_hashlib.openssl_md5} 1 0.000 0.000 0.000 0.000 JpegPresets.py:67(<module>) 25 0.000 0.000 0.000 0.000 posixpath.py:68(join) 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:34(<module>) 1 0.000 0.000 0.000 0.000 JpegImagePlugin.py:35(<module>) 25 0.000 0.000 0.000 0.000 {PIL._imaging.zip_encoder} 8 0.000 0.000 0.000 0.000 _weakrefset.py:20(__enter__) 25 0.000 0.000 0.000 0.000 Image.py:394(_getencoder) 25 0.000 0.000 0.002 0.000 ImageFont.py:200(truetype) 25 0.000 0.000 0.000 0.000 Image.py:519(__getattr__) 25 0.000 0.000 0.000 0.000 posixpath.py:104(splitext) 75 0.000 0.000 0.000 0.000 _util.py:6(isPath) 29 0.000 0.000 0.000 0.000 {method 'search' of '_sre.SRE_Pattern' objects} 5 0.000 0.000 0.000 0.000 {built-in method __new__ of type object at 0x91d400} 25 0.000 0.000 0.000 0.000 {method 'hexdigest' of '_hashlib.HASH' objects} 50 0.000 0.000 0.000 0.000 {method 'rfind' of 'str' objects} 25 0.000 0.000 0.002 0.000 ImageFont.py:123(__init__) 1 0.000 0.000 0.000 0.000 ascii.py:8(<module>) 25 0.000 0.000 0.000 0.000 ImageDraw.py:137(_getink) 8 0.000 0.000 0.000 0.000 abc.py:148(__subclasscheck__) 58 0.000 0.000 0.000 0.000 random.py:236(randint) 225 0.000 0.000 0.000 0.000 ImageFilter.py:58(__init__) 58 0.000 0.000 0.000 0.000 {min} 1 0.000 0.000 0.000 0.000 {__import__} 164 0.000 0.000 0.000 0.000 {method 'get' of 'dict' objects} 77 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects} 2 0.000 0.000 0.000 0.000 sre_parse.py:379(_parse) 4 0.000 0.000 0.000 0.000 abc.py:86(__new__) 50 0.000 0.000 0.000 0.000 {max} 25 0.000 0.000 0.005 0.000 ImageFont.py:142(getsize) 1 0.000 0.000 0.000 0.000 PpmImagePlugin.py:18(<module>) 25 0.000 0.000 0.006 0.000 PngImagePlugin.py:490(write) 19 0.000 0.000 0.000 0.000 _weakrefset.py:36(__init__) 25 0.000 0.000 0.000 0.000 {method 'setimage' of 'ImagingEncoder' objects} 4/2 0.000 0.000 0.000 0.000 sre_compile.py:32(_compile) 50 0.000 0.000 0.000 0.000 {method 'draw_ink' of 'ImagingDraw' objects} 19 0.000 0.000 0.000 0.000 _weakrefset.py:58(__iter__) 25 0.000 0.000 0.000 0.000 {method 'startswith' of 'str' objects} 1 0.000 0.000 0.000 0.000 ImagePalette.py:19(<module>) 17 0.000 0.000 0.000 0.000 sre_parse.py:182(__next) 8 0.000 0.000 0.000 0.000 abc.py:105(register) 25 0.000 0.000 0.000 0.000 {method 'endswith' of 'str' objects} 6/4 0.000 0.000 0.000 0.000 sre_parse.py:140(getwidth) 25 0.000 0.000 0.000 0.000 PngImagePlugin.py:487(__init__) 25 0.000 0.000 0.000 0.000 {PIL._imaging.draw} 5 0.000 0.000 0.000 0.000 sre_compile.py:178(_compile_charset) 2 0.000 0.000 0.000 0.000 re.py:226(_compile) 5 0.000 0.000 0.000 0.000 Image.py:2131(register_open) 2 0.000 0.000 0.000 0.000 sre_compile.py:359(_compile_info) 2 0.000 0.000 0.000 0.000 sre_compile.py:493(compile) 2 0.000 0.000 0.000 0.000 sre_parse.py:675(parse) 12 0.000 0.000 0.000 0.000 sre_parse.py:130(__getitem__) 25 0.000 0.000 0.000 0.000 {callable} 16 0.000 0.000 0.000 0.000 _weakrefset.py:83(add) 35 0.000 0.000 0.000 0.000 {method 'lower' of 'str' objects} 2 0.000 0.000 0.000 0.000 locale.py:363(normalize) 1 0.000 0.000 0.000 0.000 __init__.py:71(search_function) 10 0.000 0.000 0.000 0.000 Image.py:2168(register_extension) 1 0.000 0.000 0.000 0.000 locale.py:493(getdefaultlocale) 27/16 0.000 0.000 0.000 0.000 {issubclass} 48 0.000 0.000 0.000 0.000 {method 'upper' of 'str' objects} 5 0.000 0.000 0.000 0.000 sre_compile.py:207(_optimize_charset) 1 0.000 0.000 0.000 0.000 {method 'encode' of 'unicode' objects} 25 0.000 0.000 0.000 0.000 ImageFile.py:62(_tilesort) 2 0.000 0.000 0.000 0.000 __init__.py:49(normalize_encoding) 8 0.000 0.000 0.000 0.000 _weakrefset.py:26(__exit__) 8 0.000 0.000 0.000 0.000 _weakrefset.py:16(__init__) 3 0.000 0.000 0.000 0.000 UserDict.py:58(get) 4 0.000 0.000 0.000 0.000 sre_compile.py:472(isstring) 9 0.000 0.000 0.000 0.000 sre_parse.py:138(append) 2 0.000 0.000 0.000 0.000 sre_parse.py:301(_parse_sub) 24 0.000 0.000 0.000 0.000 {method 'add' of 'set' objects} 8 0.000 0.000 0.000 0.000 sre_parse.py:126(__len__) 4 0.000 0.000 0.000 0.000 {method 'split' of 'str' objects} 8 0.000 0.000 0.000 0.000 _weakrefset.py:52(_commit_removals) 2 0.000 0.000 0.000 0.000 sre_compile.py:478(_code) 2 0.000 0.000 0.000 0.000 {_sre.compile} 1 0.000 0.000 0.000 0.000 {_codecs.utf_8_decode} 1 0.000 0.000 0.000 0.000 ascii.py:41(getregentry) 1 0.000 0.000 0.000 0.000 locale.py:347(_replace_encoding) 1 0.000 0.000 0.000 0.000 locale.py:546(getlocale) 2 0.000 0.000 0.000 0.000 locale.py:447(_parse_localename) 5 0.000 0.000 0.000 0.000 Image.py:2157(register_save) 1 0.000 0.000 0.000 0.000 ImagePalette.py:23(ImagePalette) 1 0.000 0.000 0.000 0.000 codecs.py:77(__new__) 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:78(ChunkStream) 4 0.000 0.000 0.000 0.000 abc.py:89(<genexpr>) 4 0.000 0.000 0.000 0.000 sre_parse.py:195(match) 1 0.000 0.000 0.000 0.000 {method 'decode' of 'str' objects} 1 0.000 0.000 0.000 0.000 UserDict.py:18(__getitem__) 15 0.000 0.000 0.000 0.000 sre_parse.py:201(get) 2 0.000 0.000 0.000 0.000 sre_compile.py:354(_simple) 8 0.000 0.000 0.000 0.000 {method 'remove' of 'set' objects} 1 0.000 0.000 0.000 0.000 GifImagePlugin.py:53(GifImageFile) 2 0.000 0.000 0.000 0.000 re.py:188(compile) 3 0.000 0.000 0.000 0.000 {method 'replace' of 'str' objects} 2 0.000 0.000 0.000 0.000 sre_parse.py:178(__init__) 1 0.000 0.000 0.000 0.000 ImageFile.py:70(ImageFile) 4 0.000 0.000 0.000 0.000 sre_parse.py:90(__init__) 8 0.000 0.000 0.000 0.000 {method '__subclasshook__' of 'object' objects} 2 0.000 0.000 0.000 0.000 sre_parse.py:67(__init__) 1 0.000 0.000 0.000 0.000 ascii.py:13(Codec) 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:179(PngStream) 6 0.000 0.000 0.000 0.000 {method 'items' of 'dict' objects} 1 0.000 0.000 0.000 0.000 {_locale.setlocale} 1 0.000 0.000 0.000 0.000 {method 'index' of 'str' objects} 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:341(PngImageFile) 1 0.000 0.000 0.000 0.000 ImageFile.py:298(Parser) 1 0.000 0.000 0.000 0.000 utf_8.py:15(decode) 4 0.000 0.000 0.000 0.000 {method 'translate' of 'str' objects} 3 0.000 0.000 0.000 0.000 UserDict.py:70(__contains__) 4 0.000 0.000 0.000 0.000 sre_parse.py:257(_escape) 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:484(_idat) 1 0.000 0.000 0.000 0.000 BmpImagePlugin.py:59(BmpImageFile) 1 0.000 0.000 0.000 0.000 ImageFile.py:268(StubImageFile) 1 0.000 0.000 0.000 0.000 ascii.py:24(IncrementalDecoder) 2 0.000 0.000 0.000 0.000 sre_parse.py:134(__setitem__) 1 0.000 0.000 0.000 0.000 BmpImagePlugin.py:171(DibImageFile) 3 0.000 0.000 0.000 0.000 Image.py:2146(register_mime) 1 0.000 0.000 0.000 0.000 ascii.py:20(IncrementalEncoder) 1 0.000 0.000 0.000 0.000 io.py:75(BufferedIOBase) 1 0.000 0.000 0.000 0.000 PpmImagePlugin.py:56(PpmImageFile) 1 0.000 0.000 0.000 0.000 io.py:69(IOBase) 8 0.000 0.000 0.000 0.000 {method '__subclasses__' of 'type' objects} 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:154(PngInfo) 1 0.000 0.000 0.000 0.000 JpegImagePlugin.py:267(JpegImageFile) 1 0.000 0.000 0.000 0.000 ascii.py:28(StreamWriter) 1 0.000 0.000 0.000 0.000 io.py:78(TextIOBase) 3 0.000 0.000 0.000 0.000 {ord} 1 0.000 0.000 0.000 0.000 ascii.py:34(StreamConverter) 1 0.000 0.000 0.000 0.000 ascii.py:31(StreamReader) 1 0.000 0.000 0.000 0.000 io.py:72(RawIOBase) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 907540 function calls in 17.809 seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 36383 5.530 0.000 5.530 0.000 {method 'crop' of 'ImagingCore' objects} 450 4.446 0.010 4.446 0.010 {method 'rotate' of 'ImagingCore' objects} 675 2.115 0.003 2.115 0.003 {method 'filter' of 'ImagingCore' objects} 36358 1.425 0.000 1.425 0.000 {method 'paste' of 'ImagingCore' objects} 275 0.773 0.003 0.773 0.003 {PIL._imaging.fill} 225 0.613 0.003 17.493 0.078 captcha-old.py:52(wobbly_copy) 36383 0.517 0.000 6.068 0.000 Image.py:1729(load) 225 0.445 0.002 0.445 0.002 {PIL._imaging.blend} 36358 0.362 0.000 8.158 0.000 Image.py:1046(paste) 675 0.143 0.000 0.143 0.000 {method 'getband' of 'ImagingCore' objects} 36383 0.137 0.000 0.226 0.000 Image.py:1712(__init__) 74866 0.135 0.000 0.161 0.000 Image.py:628(load) 1850 0.102 0.000 0.110 0.000 Image.py:472(_new) 38483 0.097 0.000 0.097 0.000 Image.py:461(__init__) 36383 0.096 0.000 0.387 0.000 Image.py:785(crop) 109074 0.080 0.000 0.159 0.000 Image.py:104(isImageType) 109324 0.080 0.000 0.080 0.000 {hasattr} 37033 0.077 0.000 0.084 0.000 random.py:356(uniform) 25 0.067 0.003 0.067 0.003 {method 'point' of 'ImagingCore' objects} 675 0.064 0.000 0.064 0.000 {method 'putband' of 'ImagingCore' objects} 25 0.057 0.002 0.131 0.005 ImageOps.py:353(invert) 111249 0.047 0.000 0.047 0.000 {method 'pixel_access' of 'ImagingCore' objects} 25 0.042 0.002 0.042 0.002 {method 'encode' of 'ImagingEncoder' objects} 25 0.032 0.001 0.032 0.001 {open} 250 0.032 0.000 0.032 0.000 {method 'getbbox' of 'ImagingCore' objects} 225 0.031 0.000 0.031 0.000 {PIL._imaging.new} 225 0.030 0.000 2.448 0.011 ImageEnhance.py:85(__init__) 36633 0.028 0.000 0.051 0.000 _util.py:4(isStringType) 36358 0.025 0.000 0.025 0.000 {math.sin} 36983 0.024 0.000 0.025 0.000 {isinstance} 25 0.022 0.001 0.022 0.001 {method 'draw_bitmap' of 'ImagingDraw' objects} 225 0.019 0.000 0.121 0.001 Image.py:2104(merge) 25 0.016 0.001 0.016 0.001 {method 'render' of 'Font' objects} 25 0.012 0.000 17.805 0.712 captcha-old.py:77(gen_captcha) 250 0.011 0.000 0.011 0.000 {method 'write' of 'file' objects} 25 0.011 0.000 0.072 0.003 PngImagePlugin.py:493(_save) 50 0.009 0.000 0.009 0.000 {method 'getsize' of 'Font' objects} 37241 0.009 0.000 0.009 0.000 {len} 37130 0.007 0.000 0.007 0.000 {method 'random' of '_random.Random' objects} 225 0.006 0.000 2.418 0.011 Image.py:831(filter) 450 0.004 0.000 4.502 0.010 Image.py:1338(rotate) 25 0.003 0.000 0.003 0.000 {method 'close' of 'file' objects} 36 0.002 0.000 0.003 0.000 captcha-old.py:131(try_pick_word) 25 0.002 0.000 0.002 0.000 {method 'flush' of 'file' objects} 250 0.002 0.000 0.803 0.003 Image.py:1765(new) 675 0.002 0.000 2.117 0.003 ImageFilter.py:51(filter) 25 0.002 0.000 0.002 0.000 {PIL._imagingft.getfont} 751 0.002 0.000 0.002 0.000 {range} 450 0.001 0.000 0.002 0.000 Image.py:300(getmodebands) 150 0.001 0.000 0.001 0.000 {PIL._imaging.crc32} 800 0.001 0.000 0.001 0.000 _binary.py:18(o8) 225 0.001 0.000 0.449 0.002 Image.py:2048(blend) 7075 0.001 0.000 0.001 0.000 {method 'append' of 'list' objects} 25 0.001 0.000 0.048 0.002 ImageFile.py:435(_save) 900 0.001 0.000 0.001 0.000 ImageMode.py:36(getmode) 225 0.001 0.000 0.002 0.000 abc.py:128(__instancecheck__) 75 0.001 0.000 0.010 0.000 PngImagePlugin.py:474(putchunk) 125 0.001 0.000 0.002 0.000 _binary.py:50(o32be) 1850 0.001 0.000 0.001 0.000 {method 'copy' of 'dict' objects} 225 0.001 0.000 0.001 0.000 _weakrefset.py:70(__contains__) 250 0.001 0.000 0.033 0.000 Image.py:864(getbbox) 25 0.000 0.000 0.109 0.004 Image.py:1398(save) 225 0.000 0.000 0.449 0.002 ImageEnhance.py:26(enhance) 450 0.000 0.000 0.001 0.000 Image.py:273(getmodetype) 97 0.000 0.000 0.000 0.000 random.py:173(randrange) 800 0.000 0.000 0.000 0.000 {chr} 25 0.000 0.000 0.001 0.000 ImageDraw.py:293(Draw) 25 0.000 0.000 0.073 0.003 ImageOps.py:44(_lut) 25 0.000 0.000 0.003 0.000 captcha-old.py:169(pick_word) 250 0.000 0.000 0.000 0.000 {getattr} 150 0.000 0.000 0.001 0.000 _binary.py:47(o16be) 25 0.000 0.000 0.000 0.000 ImageDraw.py:61(__init__) 25 0.000 0.000 0.073 0.003 Image.py:1130(point) 25 0.000 0.000 0.042 0.002 ImageDraw.py:258(text) 25 0.000 0.000 0.000 0.000 {_hashlib.openssl_md5} 25 0.000 0.000 0.020 0.001 ImageFont.py:151(getmask2) 25 0.000 0.000 0.000 0.000 {method 'sort' of 'list' objects} 36 0.000 0.000 0.000 0.000 {method 'search' of '_sre.SRE_Pattern' objects} 25 0.000 0.000 0.002 0.000 ImageFont.py:200(truetype) 25 0.000 0.000 0.000 0.000 genericpath.py:85(_splitext) 25 0.000 0.000 0.000 0.000 posixpath.py:68(join) 72 0.000 0.000 0.000 0.000 random.py:236(randint) 25 0.000 0.000 0.000 0.000 Image.py:394(_getencoder) 25 0.000 0.000 0.000 0.000 Image.py:316(preinit) 25 0.000 0.000 0.002 0.000 ImageFont.py:123(__init__) 75 0.000 0.000 0.000 0.000 _util.py:6(isPath) 25 0.000 0.000 0.000 0.000 ImageDraw.py:137(_getink) 25 0.000 0.000 0.000 0.000 {PIL._imaging.zip_encoder} 25 0.000 0.000 0.000 0.000 {method 'hexdigest' of '_hashlib.HASH' objects} 50 0.000 0.000 0.000 0.000 {method 'rfind' of 'str' objects} 25 0.000 0.000 0.005 0.000 ImageFont.py:142(getsize) 225 0.000 0.000 0.000 0.000 ImageFilter.py:58(__init__) 75 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects} 25 0.000 0.000 0.000 0.000 Image.py:519(__getattr__) 50 0.000 0.000 0.000 0.000 {max} 50 0.000 0.000 0.000 0.000 {min} 25 0.000 0.000 0.000 0.000 posixpath.py:104(splitext) 150 0.000 0.000 0.000 0.000 {method 'get' of 'dict' objects} 25 0.000 0.000 0.004 0.000 PngImagePlugin.py:490(write) 25 0.000 0.000 0.000 0.000 {method 'startswith' of 'str' objects} 25 0.000 0.000 0.000 0.000 {method 'setimage' of 'ImagingEncoder' objects} 50 0.000 0.000 0.000 0.000 {method 'draw_ink' of 'ImagingDraw' objects} 25 0.000 0.000 0.000 0.000 PngImagePlugin.py:487(__init__) 25 0.000 0.000 0.000 0.000 {method 'endswith' of 'str' objects} 25 0.000 0.000 0.000 0.000 {method 'upper' of 'str' objects} 25 0.000 0.000 0.000 0.000 {PIL._imaging.draw} 25 0.000 0.000 0.000 0.000 {callable} 25 0.000 0.000 0.000 0.000 {method 'lower' of 'str' objects} 25 0.000 0.000 0.000 0.000 ImageFile.py:62(_tilesort) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 927905 function calls in 17.939 seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 37232 5.545 0.000 5.545 0.000 {method 'crop' of 'ImagingCore' objects} 450 4.611 0.010 4.611 0.010 {method 'rotate' of 'ImagingCore' objects} 675 2.080 0.003 2.080 0.003 {method 'filter' of 'ImagingCore' objects} 37207 1.277 0.000 1.277 0.000 {method 'paste' of 'ImagingCore' objects} 275 0.902 0.003 0.902 0.003 {PIL._imaging.fill} 225 0.610 0.003 17.602 0.078 captcha-old.py:52(wobbly_copy) 37232 0.561 0.000 6.128 0.000 Image.py:1729(load) 225 0.418 0.002 0.418 0.002 {PIL._imaging.blend} 37207 0.338 0.000 8.006 0.000 Image.py:1046(paste) 675 0.196 0.000 0.196 0.000 {method 'getband' of 'ImagingCore' objects} 76564 0.186 0.000 0.212 0.000 Image.py:628(load) 37232 0.149 0.000 0.240 0.000 Image.py:1712(__init__) 39332 0.097 0.000 0.097 0.000 Image.py:461(__init__) 25 0.086 0.003 0.155 0.006 ImageOps.py:353(invert) 37232 0.083 0.000 0.417 0.000 Image.py:785(crop) 111871 0.082 0.000 0.082 0.000 {hasattr} 675 0.065 0.000 0.065 0.000 {method 'putband' of 'ImagingCore' objects} 25 0.060 0.002 0.060 0.002 {method 'point' of 'ImagingCore' objects} 37882 0.058 0.000 0.066 0.000 random.py:356(uniform) 111621 0.055 0.000 0.137 0.000 Image.py:104(isImageType) 113796 0.048 0.000 0.048 0.000 {method 'pixel_access' of 'ImagingCore' objects} 225 0.046 0.000 0.190 0.001 Image.py:2104(merge) 25 0.046 0.002 0.046 0.002 {method 'encode' of 'ImagingEncoder' objects} 250 0.041 0.000 0.041 0.000 {method 'write' of 'file' objects} 225 0.036 0.000 0.036 0.000 {PIL._imaging.new} 250 0.033 0.000 0.033 0.000 {method 'getbbox' of 'ImagingCore' objects} 37482 0.026 0.000 0.049 0.000 _util.py:4(isStringType) 37207 0.026 0.000 0.026 0.000 {math.sin} 37832 0.024 0.000 0.025 0.000 {isinstance} 25 0.018 0.001 0.018 0.001 {open} 250 0.018 0.000 0.923 0.004 Image.py:1765(new) 25 0.016 0.001 0.016 0.001 {method 'render' of 'Font' objects} 1850 0.014 0.000 0.020 0.000 Image.py:472(_new) 25 0.012 0.000 17.936 0.717 captcha-old.py:77(gen_captcha) 38087 0.009 0.000 0.009 0.000 {len} 50 0.009 0.000 0.009 0.000 {method 'getsize' of 'Font' objects} 37977 0.008 0.000 0.008 0.000 {method 'random' of '_random.Random' objects} 225 0.006 0.000 2.482 0.011 Image.py:831(filter) 25 0.005 0.000 0.005 0.000 {method 'flush' of 'file' objects} 25 0.005 0.000 0.005 0.000 {method 'draw_bitmap' of 'ImagingDraw' objects} 25 0.004 0.000 0.004 0.000 {method 'close' of 'file' objects} 450 0.004 0.000 4.623 0.010 Image.py:1338(rotate) 35 0.002 0.000 0.002 0.000 captcha-old.py:131(try_pick_word) 675 0.002 0.000 2.081 0.003 ImageFilter.py:51(filter) 75 0.002 0.000 0.015 0.000 PngImagePlugin.py:474(putchunk) 25 0.002 0.000 0.002 0.000 {PIL._imagingft.getfont} 225 0.002 0.000 2.484 0.011 ImageEnhance.py:85(__init__) 751 0.002 0.000 0.002 0.000 {range} 900 0.001 0.000 0.001 0.000 ImageMode.py:36(getmode) 150 0.001 0.000 0.001 0.000 {PIL._imaging.crc32} 450 0.001 0.000 0.003 0.000 Image.py:300(getmodebands) 250 0.001 0.000 0.035 0.000 Image.py:864(getbbox) 25 0.001 0.000 0.123 0.005 Image.py:1398(save) 225 0.001 0.000 0.421 0.002 Image.py:2048(blend) 7075 0.001 0.000 0.001 0.000 {method 'append' of 'list' objects} 25 0.001 0.000 0.056 0.002 ImageFile.py:435(_save) 25 0.001 0.000 0.099 0.004 PngImagePlugin.py:493(_save) 800 0.001 0.000 0.001 0.000 _binary.py:18(o8) 225 0.001 0.000 0.002 0.000 abc.py:128(__instancecheck__) 1850 0.001 0.000 0.001 0.000 {method 'copy' of 'dict' objects} 225 0.001 0.000 0.001 0.000 _weakrefset.py:70(__contains__) 125 0.001 0.000 0.001 0.000 _binary.py:50(o32be) 225 0.000 0.000 0.422 0.002 ImageEnhance.py:26(enhance) 450 0.000 0.000 0.001 0.000 Image.py:273(getmodetype) 95 0.000 0.000 0.000 0.000 random.py:173(randrange) 25 0.000 0.000 0.068 0.003 ImageOps.py:44(_lut) 25 0.000 0.000 0.001 0.000 ImageDraw.py:293(Draw) 25 0.000 0.000 0.003 0.000 captcha-old.py:169(pick_word) 250 0.000 0.000 0.000 0.000 {getattr} 800 0.000 0.000 0.000 0.000 {chr} 25 0.000 0.000 0.000 0.000 ImageDraw.py:61(__init__) 150 0.000 0.000 0.001 0.000 _binary.py:47(o16be) 25 0.000 0.000 0.068 0.003 Image.py:1130(point) 25 0.000 0.000 0.027 0.001 ImageDraw.py:258(text) 25 0.000 0.000 0.021 0.001 ImageFont.py:151(getmask2) 25 0.000 0.000 0.000 0.000 {method 'sort' of 'list' objects} 25 0.000 0.000 0.000 0.000 {_hashlib.openssl_md5} 25 0.000 0.000 0.000 0.000 genericpath.py:85(_splitext) 25 0.000 0.000 0.000 0.000 posixpath.py:68(join) 35 0.000 0.000 0.000 0.000 {method 'search' of '_sre.SRE_Pattern' objects} 25 0.000 0.000 0.002 0.000 ImageFont.py:200(truetype) 75 0.000 0.000 0.000 0.000 _util.py:6(isPath) 50 0.000 0.000 0.000 0.000 {method 'rfind' of 'str' objects} 25 0.000 0.000 0.000 0.000 Image.py:394(_getencoder) 70 0.000 0.000 0.000 0.000 random.py:236(randint) 25 0.000 0.000 0.000 0.000 {PIL._imaging.zip_encoder} 25 0.000 0.000 0.000 0.000 ImageDraw.py:137(_getink) 25 0.000 0.000 0.002 0.000 ImageFont.py:123(__init__) 25 0.000 0.000 0.000 0.000 {method 'hexdigest' of '_hashlib.HASH' objects} 25 0.000 0.000 0.005 0.000 ImageFont.py:142(getsize) 25 0.000 0.000 0.000 0.000 Image.py:519(__getattr__) 75 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects} 50 0.000 0.000 0.000 0.000 {max} 50 0.000 0.000 0.000 0.000 {min} 25 0.000 0.000 0.000 0.000 posixpath.py:104(splitext) 25 0.000 0.000 0.009 0.000 PngImagePlugin.py:490(write) 225 0.000 0.000 0.000 0.000 ImageFilter.py:58(__init__) 25 0.000 0.000 0.000 0.000 {method 'setimage' of 'ImagingEncoder' objects} 150 0.000 0.000 0.000 0.000 {method 'get' of 'dict' objects} 25 0.000 0.000 0.000 0.000 {method 'startswith' of 'str' objects} 50 0.000 0.000 0.000 0.000 {method 'draw_ink' of 'ImagingDraw' objects} 25 0.000 0.000 0.000 0.000 PngImagePlugin.py:487(__init__) 25 0.000 0.000 0.000 0.000 Image.py:316(preinit) 25 0.000 0.000 0.000 0.000 {PIL._imaging.draw} 25 0.000 0.000 0.000 0.000 {method 'endswith' of 'str' objects} 25 0.000 0.000 0.000 0.000 {callable} 25 0.000 0.000 0.000 0.000 {method 'lower' of 'str' objects} 25 0.000 0.000 0.000 0.000 ImageFile.py:62(_tilesort) 25 0.000 0.000 0.000 0.000 {method 'upper' of 'str' objects} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} real 0m18.130s user 0m27.776s sys 0m2.972s reedy@terbium:~$
I do note, python is python 2.7... I wonder what python3 (3.4) makes much difference...
Back to my vm
Python 2.7.12+
$ time python 'captcha-old.py' --key 'CHANGE_THIS_SECRET!' --output '/tmp/mw-fancycaptcha-1486771866-0b4ca9' --count '100' --dirs '0' --wordlist '/home/reedy/words' --font '/usr/share/fonts/truetype/freefont/FreeMonoBoldOblique.ttf' --blacklist '/home/reedy/badwords' Generating 100 CAPTCHA images separated in 100 image(s) per chunk run by 1 threads... 4069456 function calls (4069180 primitive calls) in 29.519 seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 1800 13.110 0.007 13.110 0.007 {method 'transform2' of 'ImagingCore' objects} 2700 4.672 0.002 4.672 0.002 {method 'filter' of 'ImagingCore' objects} 900 1.460 0.002 1.460 0.002 {PIL._imaging.blend} 149515 1.261 0.000 3.735 0.000 Image.py:1255(paste) 900 1.195 0.001 28.680 0.032 captcha-old.py:52(wobbly_copy) 149615 0.727 0.000 1.663 0.000 Image.py:1955(__init__) 299233 0.614 0.000 0.614 0.000 {map} 309430 0.544 0.000 0.692 0.000 Image.py:747(load) 149615 0.473 0.000 0.473 0.000 {method 'crop' of 'ImagingCore' objects} 149615 0.472 0.000 1.015 0.000 Image.py:1974(load) 2700 0.407 0.000 0.407 0.000 {method 'getband' of 'ImagingCore' objects} 149615 0.404 0.000 2.424 0.000 Image.py:1012(crop) 159815 0.354 0.000 0.354 0.000 Image.py:499(__init__) 451548 0.345 0.000 0.345 0.000 {hasattr} 2700 0.339 0.000 0.339 0.000 {method 'putband' of 'ImagingCore' objects} 2700 0.320 0.000 0.320 0.000 {PIL._imaging.new} 448545 0.319 0.000 0.658 0.000 Image.py:136(isImageType) 100 0.264 0.003 0.264 0.003 {method 'encode' of 'ImagingEncoder' objects} 149515 0.233 0.000 0.233 0.000 {method 'paste' of 'ImagingCore' objects} 1000 0.231 0.000 0.231 0.000 {method 'write' of 'file' objects} 459045 0.218 0.000 0.218 0.000 {method 'pixel_access' of 'ImagingCore' objects} 152215 0.216 0.000 0.257 0.000 random.py:358(uniform) 1000 0.183 0.000 0.183 0.000 {method 'getbbox' of 'ImagingCore' objects} 154196/154195 0.134 0.000 0.148 0.000 {isinstance} 1100 0.126 0.000 0.126 0.000 {PIL._imaging.fill} 150615 0.125 0.000 0.253 0.000 _util.py:4(isStringType) 153115 0.085 0.000 0.085 0.000 {math.sin} 100 0.070 0.001 0.070 0.001 {method 'render' of 'Font' objects} 7400 0.048 0.000 0.076 0.000 Image.py:519(_new) 152563 0.041 0.000 0.041 0.000 {method 'random' of '_random.Random' objects} 156509/156468 0.041 0.000 0.041 0.000 {len} 200 0.041 0.000 0.041 0.000 {method 'getsize' of 'Font' objects} 7200 0.037 0.000 0.037 0.000 {round} 1800 0.037 0.000 13.488 0.007 Image.py:1550(rotate) 900 0.036 0.000 5.689 0.006 Image.py:1058(filter) 900 0.025 0.000 0.508 0.001 Image.py:2394(merge) 2800 0.018 0.000 0.390 0.000 Image.py:2013(new) 1800 0.018 0.000 13.137 0.007 Image.py:1863(__transformer) 1800 0.018 0.000 13.403 0.007 Image.py:1811(transform) 100 0.017 0.000 29.499 0.295 captcha-old.py:77(gen_captcha) 900 0.014 0.000 5.706 0.006 ImageEnhance.py:95(__init__) 100 0.013 0.000 0.013 0.000 {method 'draw_bitmap' of 'ImagingDraw' objects} 100 0.013 0.000 0.013 0.000 {open} 3003 0.012 0.000 0.012 0.000 {range} 100 0.012 0.000 0.012 0.000 {PIL._imagingft.getfont} 100 0.011 0.000 0.047 0.000 ImageOps.py:357(invert) 124 0.010 0.000 0.013 0.000 captcha-old.py:131(try_pick_word) 2700 0.009 0.000 4.680 0.002 ImageFilter.py:51(filter) 900 0.007 0.000 0.014 0.000 abc.py:128(__instancecheck__) 1800 0.007 0.000 0.011 0.000 Image.py:333(getmodebands) 29161 0.007 0.000 0.007 0.000 {method 'append' of 'list' objects} 100 0.006 0.000 0.006 0.000 {method 'point' of 'ImagingCore' objects} 900 0.006 0.000 1.482 0.002 Image.py:2338(blend) 906 0.005 0.000 0.005 0.000 _weakrefset.py:70(__contains__) 600 0.005 0.000 0.005 0.000 {PIL._imaging.crc32} 4500 0.005 0.000 0.005 0.000 ImageMode.py:33(getmode) 100 0.004 0.000 0.522 0.005 PngImagePlugin.py:668(_save) 100 0.004 0.000 0.508 0.005 ImageFile.py:443(_save) 1000 0.004 0.000 0.193 0.000 Image.py:1092(getbbox) 3600 0.004 0.000 0.004 0.000 {math.cos} 7400 0.004 0.000 0.004 0.000 {method 'copy' of 'dict' objects} 300 0.004 0.000 0.241 0.001 PngImagePlugin.py:646(putchunk) 100 0.003 0.000 0.568 0.006 Image.py:1612(save) 1800 0.003 0.000 0.003 0.000 Image.py:1589(transform) 900 0.003 0.000 1.485 0.002 ImageEnhance.py:26(enhance) 1800 0.003 0.000 0.004 0.000 Image.py:306(getmodetype) 1 0.003 0.003 0.021 0.021 JpegImagePlugin.py:35(<module>) 1473 0.003 0.000 0.003 0.000 sre_parse.py:193(__next) 46/7 0.002 0.000 0.008 0.001 sre_parse.py:395(_parse) 348 0.002 0.000 0.002 0.000 random.py:175(randrange) 900 0.002 0.000 0.003 0.000 Image.py:1082(getbands) 1100 0.002 0.000 0.002 0.000 {_struct.pack} 100 0.002 0.000 0.031 0.000 ImageOps.py:47(_lut) 100 0.001 0.000 0.001 0.000 {method 'flush' of 'file' objects} 1245 0.001 0.000 0.001 0.000 {getattr} 2 0.001 0.001 0.002 0.001 collections.py:305(namedtuple) 1800 0.001 0.000 0.001 0.000 {math.radians} 100 0.001 0.000 0.003 0.000 ImageDraw.py:285(Draw) 100 0.001 0.000 0.017 0.000 captcha-old.py:169(pick_word) 100 0.001 0.000 0.002 0.000 ImageDraw.py:49(__init__) 100 0.001 0.000 0.026 0.000 Image.py:349(preinit) 1 0.001 0.001 0.015 0.015 fractions.py:4(<module>) 1354 0.001 0.000 0.004 0.000 sre_parse.py:212(get) 100 0.001 0.000 0.001 0.000 {method 'close' of 'file' objects} 100 0.001 0.000 0.104 0.001 ImageDraw.py:220(text) 86/7 0.001 0.000 0.002 0.000 sre_compile.py:64(_compile) 1 0.001 0.001 0.001 0.001 ImagePalette.py:19(<module>) 100 0.001 0.000 0.029 0.000 Image.py:1339(point) 100 0.001 0.000 0.001 0.000 {_hashlib.openssl_md5} 1 0.001 0.001 0.018 0.018 TiffImagePlugin.py:42(<module>) 1 0.001 0.001 0.009 0.009 decimal.py:116(<module>) 100 0.001 0.000 0.001 0.000 genericpath.py:93(_splitext) 900 0.001 0.000 0.001 0.000 ImageFilter.py:58(__init__) 100 0.001 0.000 0.013 0.000 ImageFont.py:119(__init__) 500 0.001 0.000 0.002 0.000 _binary.py:73(o32be) 600 0.001 0.000 0.001 0.000 _binary.py:69(o16be) 100 0.001 0.000 0.001 0.000 {PIL._imaging.zip_encoder} 100 0.001 0.000 0.001 0.000 {method 'sort' of 'list' objects} 100 0.001 0.000 0.089 0.001 ImageFont.py:150(getmask2) 100 0.001 0.000 0.002 0.000 Image.py:426(_getencoder) 248 0.001 0.000 0.002 0.000 random.py:238(randint) 100 0.001 0.000 0.014 0.000 ImageFont.py:216(truetype) 100 0.001 0.000 0.001 0.000 {method 'hexdigest' of '_hashlib.HASH' objects} 100 0.001 0.000 0.001 0.000 posixpath.py:61(join) 124 0.000 0.000 0.000 0.000 {method 'search' of '_sre.SRE_Pattern' objects} 100 0.000 0.000 0.002 0.000 posixpath.py:97(splitext) 202 0.000 0.000 0.000 0.000 {method 'rfind' of 'str' objects} 113/42 0.000 0.000 0.001 0.000 sre_parse.py:151(getwidth) 1 0.000 0.000 0.000 0.000 GifImagePlugin.py:27(<module>) 100 0.000 0.000 0.024 0.000 ImageFont.py:140(getsize) 331 0.000 0.000 0.001 0.000 sre_parse.py:141(__getitem__) 1 0.000 0.000 0.002 0.002 BmpImagePlugin.py:27(<module>) 100 0.000 0.000 0.001 0.000 ImageDraw.py:112(_getink) 100 0.000 0.000 0.000 0.000 Image.py:617(__getattr__) 200 0.000 0.000 0.001 0.000 _util.py:7(isPath) 363 0.000 0.000 0.000 0.000 {min} 1 0.000 0.000 0.001 0.001 PngImagePlugin.py:34(<module>) 40/7 0.000 0.000 0.008 0.001 sre_parse.py:317(_parse_sub) 100 0.000 0.000 0.236 0.002 PngImagePlugin.py:664(write) 100 0.000 0.000 0.000 0.000 ImageDraw.py:209(_multiline_check) 306 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects} 865 0.000 0.000 0.000 0.000 {method 'get' of 'dict' objects} 207 0.000 0.000 0.000 0.000 {max} 1 0.000 0.000 0.001 0.001 TiffTags.py:343(_populate) 111 0.000 0.000 0.000 0.000 {built-in method __new__ of type object at 0x5617ae60e280} 100 0.000 0.000 0.000 0.000 {method 'setimage' of 'ImagingEncoder' objects} 28 0.000 0.000 0.000 0.000 sre_compile.py:256(_optimize_charset) 200 0.000 0.000 0.000 0.000 {method 'draw_ink' of 'ImagingDraw' objects} 3 0.000 0.000 0.000 0.000 UserDict.py:91(get) 100 0.000 0.000 0.000 0.000 PngImagePlugin.py:660(__init__) 272 0.000 0.000 0.000 0.000 sre_parse.py:206(match) 100 0.000 0.000 0.000 0.000 TiffTags.py:26(__new__) 71 0.000 0.000 0.000 0.000 collections.py:349(<genexpr>) 1 0.000 0.000 0.000 0.000 ImageFile.py:30(<module>) 28 0.000 0.000 0.000 0.000 sre_compile.py:228(_compile_charset) 7 0.000 0.000 0.011 0.002 re.py:230(_compile) 9 0.000 0.000 0.000 0.000 _weakrefset.py:58(__iter__) 1 0.000 0.000 0.000 0.000 <string>:1(DecimalTuple) 4 0.000 0.000 0.001 0.000 abc.py:86(__new__) 1 0.000 0.000 0.001 0.001 PpmImagePlugin.py:18(<module>) 156 0.000 0.000 0.000 0.000 sre_parse.py:137(__len__) 100 0.000 0.000 0.000 0.000 {method 'cleanup' of 'ImagingEncoder' objects} 6/2 0.000 0.000 0.000 0.000 abc.py:148(__subclasscheck__) 113 0.000 0.000 0.000 0.000 {method 'startswith' of 'str' objects} 35 0.000 0.000 0.000 0.000 sre_compile.py:428(_simple) 230 0.000 0.000 0.000 0.000 {method 'upper' of 'str' objects} 100 0.000 0.000 0.000 0.000 {PIL._imaging.draw} 106 0.000 0.000 0.000 0.000 sre_parse.py:149(append) 100 0.000 0.000 0.000 0.000 {method 'endswith' of 'str' objects} 1 0.000 0.000 0.002 0.002 TiffTags.py:20(<module>) 19 0.000 0.000 0.000 0.000 sre_parse.py:227(isname) 1 0.000 0.000 0.000 0.000 ascii.py:8(<module>) 100 0.000 0.000 0.000 0.000 ImageFile.py:66(_tilesort) 100 0.000 0.000 0.000 0.000 <string>:8(__new__) 4 0.000 0.000 0.000 0.000 abc.py:89(<genexpr>) 1 0.000 0.000 0.000 0.000 {__import__} 112 0.000 0.000 0.000 0.000 {method 'lower' of 'str' objects} 3 0.000 0.000 0.000 0.000 decimal.py:3782(__init__) 1 0.000 0.000 0.000 0.000 GimpGradientFile.py:16(<module>) 7 0.000 0.000 0.011 0.002 sre_compile.py:567(compile) 86 0.000 0.000 0.000 0.000 sre_parse.py:92(__init__) 100 0.000 0.000 0.000 0.000 {callable} 7 0.000 0.000 0.008 0.001 sre_parse.py:706(parse) 18 0.000 0.000 0.000 0.000 {method 'format' of 'str' objects} 6 0.000 0.000 0.000 0.000 decimal.py:514(__new__) 23 0.000 0.000 0.000 0.000 sre_parse.py:74(opengroup) 30 0.000 0.000 0.000 0.000 sre_parse.py:268(_escape) 7 0.000 0.000 0.001 0.000 sre_compile.py:433(_compile_info) 10 0.000 0.000 0.000 0.000 collections.py:375(<genexpr>) 1 0.000 0.000 0.000 0.000 locale.py:349(_replace_encoding) 7 0.000 0.000 0.000 0.000 TiffImagePlugin.py:589(_register_basic) 18 0.000 0.000 0.000 0.000 _weakrefset.py:36(__init__) 1 0.000 0.000 0.000 0.000 TiffImagePlugin.py:378(ImageFileDirectory_v2) 104 0.000 0.000 0.000 0.000 sre_parse.py:221(isident) 1 0.000 0.000 0.000 0.000 GimpPaletteFile.py:17(<module>) 1 0.000 0.000 0.000 0.000 <string>:1(<module>) 56 0.000 0.000 0.000 0.000 {method 'find' of 'bytearray' objects} 1 0.000 0.000 0.000 0.000 decimal.py:505(Decimal) 5 0.000 0.000 0.000 0.000 _weakrefset.py:16(__init__) 5 0.000 0.000 0.000 0.000 TiffImagePlugin.py:575(decorator) 1 0.000 0.000 0.000 0.000 fractions.py:44(Fraction) 27 0.000 0.000 0.000 0.000 decimal.py:3809(<genexpr>) 24 0.000 0.000 0.000 0.000 {setattr} 7 0.000 0.000 0.003 0.000 sre_compile.py:552(_code) 21 0.000 0.000 0.000 0.000 {method 'items' of 'dict' objects} 1 0.000 0.000 0.000 0.000 PaletteFile.py:16(<module>) 1 0.000 0.000 0.000 0.000 TiffImagePlugin.py:257(IFDRational) 1 0.000 0.000 0.000 0.000 locale.py:495(getdefaultlocale) 24 0.000 0.000 0.000 0.000 {method 'replace' of 'str' objects} 2 0.000 0.000 0.000 0.000 sre_compile.py:411(_mk_bitmap) 7 0.000 0.000 0.011 0.002 re.py:192(compile) 1 0.000 0.000 0.000 0.000 ImageSequence.py:19(<module>) 12 0.000 0.000 0.000 0.000 Image.py:2472(register_extension) 10 0.000 0.000 0.000 0.000 {all} 2 0.000 0.000 0.000 0.000 locale.py:365(normalize) 35 0.000 0.000 0.000 0.000 sre_parse.py:145(__setitem__) 7 0.000 0.000 0.000 0.000 {_sre.compile} 19 0.000 0.000 0.000 0.000 ImageMode.py:23(__init__) 14 0.000 0.000 0.000 0.000 sre_compile.py:546(isstring) 23 0.000 0.000 0.000 0.000 sre_parse.py:85(closegroup) 6 0.000 0.000 0.000 0.000 Image.py:2423(register_open) 27 0.000 0.000 0.000 0.000 decimal.py:3816(<genexpr>) 27 0.000 0.000 0.000 0.000 {_sre.getlower} 28 0.000 0.000 0.000 0.000 TiffImagePlugin.py:335(_delegate) 1 0.000 0.000 0.000 0.000 __init__.py:71(search_function) 7 0.000 0.000 0.000 0.000 _weakrefset.py:83(add) 3 0.000 0.000 0.000 0.000 {method 'match' of '_sre.SRE_Pattern' objects} 1 0.000 0.000 0.000 0.000 <string>:1(_TagInfo) 5 0.000 0.000 0.000 0.000 fractions.py:280(_operator_fallbacks) 1 0.000 0.000 0.000 0.000 JpegPresets.py:67(<module>) 5 0.000 0.000 0.000 0.000 _weakrefset.py:26(__exit__) 1 0.000 0.000 0.000 0.000 decimal.py:3763(Context) 10/2 0.000 0.000 0.000 0.000 {issubclass} 23 0.000 0.000 0.000 0.000 {method 'remove' of 'list' objects} 10 0.000 0.000 0.000 0.000 collections.py:373(<genexpr>) 5 0.000 0.000 0.000 0.000 _weakrefset.py:20(__enter__) 1 0.000 0.000 0.000 0.000 __init__.py:1025(getLogger) 7 0.000 0.000 0.000 0.000 sre_parse.py:189(__init__) 2 0.000 0.000 0.000 0.000 {repr} 6 0.000 0.000 0.000 0.000 Image.py:2449(register_save) 8 0.000 0.000 0.000 0.000 sre_compile.py:101(fixup) 1 0.000 0.000 0.000 0.000 __init__.py:1071(_fixupParents) 6 0.000 0.000 0.000 0.000 {method 'split' of 'str' objects} 7 0.000 0.000 0.000 0.000 {_struct.calcsize} 1 0.000 0.000 0.000 0.000 threading.py:147(acquire) 2 0.000 0.000 0.000 0.000 __init__.py:49(normalize_encoding) 1 0.000 0.000 0.000 0.000 _abcoll.py:24(_hasattr) 1 0.000 0.000 0.000 0.000 ImageChops.py:18(<module>) 61 0.000 0.000 0.000 0.000 {method 'isalnum' of 'str' objects} 1 0.000 0.000 0.000 0.000 TiffImagePlugin.py:796(ImageFileDirectory_v1) 1 0.000 0.000 0.000 0.000 {method 'encode' of 'unicode' objects} 1 0.000 0.000 0.000 0.000 TiffImagePlugin.py:889(TiffImageFile) 7 0.000 0.000 0.000 0.000 sre_parse.py:67(__init__) 1 0.000 0.000 0.000 0.000 codecs.py:92(__new__) 1 0.000 0.000 0.000 0.000 threading.py:187(release) 1 0.000 0.000 0.000 0.000 abc.py:105(register) 1 0.000 0.000 0.000 0.000 __init__.py:1127(__init__) 1 0.000 0.000 0.000 0.000 GifImagePlugin.py:53(GifImageFile) 54 0.000 0.000 0.000 0.000 {ord} 1 0.000 0.000 0.000 0.000 ascii.py:41(getregentry) 5 0.000 0.000 0.000 0.000 Image.py:2438(register_mime) 2 0.000 0.000 0.000 0.000 locale.py:449(_parse_localename) 1 0.000 0.000 0.000 0.000 {method 'decode' of 'str' objects} 1 0.000 0.000 0.000 0.000 locale.py:548(getlocale) 6 0.000 0.000 0.000 0.000 {method 'translate' of 'str' objects} 12 0.000 0.000 0.000 0.000 {method 'remove' of 'set' objects} 5 0.000 0.000 0.000 0.000 _weakrefset.py:52(_commit_removals) 1 0.000 0.000 0.000 0.000 __init__.py:1567(getLogger) 1 0.000 0.000 0.000 0.000 {_codecs.utf_8_decode} 1 0.000 0.000 0.000 0.000 BmpImagePlugin.py:61(BmpImageFile) 10 0.000 0.000 0.000 0.000 {method '__contains__' of 'frozenset' objects} 1 0.000 0.000 0.000 0.000 utf_8.py:15(decode) 2 0.000 0.000 0.000 0.000 _abcoll.py:26(<genexpr>) 1 0.000 0.000 0.000 0.000 _abcoll.py:128(__subclasshook__) 5 0.000 0.000 0.000 0.000 TiffImagePlugin.py:574(_register_loader) 1 0.000 0.000 0.000 0.000 ImageFile.py:75(ImageFile) 5 0.000 0.000 0.000 0.000 TiffImagePlugin.py:584(decorator) 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:280(PngStream) 1 0.000 0.000 0.000 0.000 ImagePalette.py:26(ImagePalette) 1 0.000 0.000 0.000 0.000 __init__.py:205(_acquireLock) 1 0.000 0.000 0.000 0.000 ascii.py:13(Codec) 4 0.000 0.000 0.000 0.000 {method 'extend' of 'list' objects} 1 0.000 0.000 0.000 0.000 ImageFile.py:304(Parser) 3 0.000 0.000 0.000 0.000 {method 'strip' of 'str' objects} 5 0.000 0.000 0.000 0.000 {method '__subclasshook__' of 'object' objects} 1 0.000 0.000 0.000 0.000 {_locale.setlocale} 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:203(PngInfo) 10 0.000 0.000 0.000 0.000 {method 'isdigit' of 'str' objects} 5 0.000 0.000 0.000 0.000 TiffImagePlugin.py:583(_register_writer) 1 0.000 0.000 0.000 0.000 JpegImagePlugin.py:282(JpegImageFile) 1 0.000 0.000 0.000 0.000 {method 'acquire' of 'thread.lock' objects} 10 0.000 0.000 0.000 0.000 {method 'group' of '_sre.SRE_Match' objects} 1 0.000 0.000 0.000 0.000 __init__.py:214(_releaseLock) 1 0.000 0.000 0.000 0.000 __init__.py:177(_checkLevel) 20 0.000 0.000 0.000 0.000 {method 'add' of 'set' objects} 3 0.000 0.000 0.000 0.000 UserDict.py:103(__contains__) 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:97(ChunkStream) 1 0.000 0.000 0.000 0.000 __init__.py:976(append) 1 0.000 0.000 0.000 0.000 GimpPaletteFile.py:24(GimpPaletteFile) 2 0.000 0.000 0.000 0.000 {sys._getframe} 1 0.000 0.000 0.000 0.000 ImageFile.py:274(StubImageFile) 2 0.000 0.000 0.000 0.000 threading.py:64(_note) 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:183(iTXt) 5 0.000 0.000 0.000 0.000 {method '__subclasses__' of 'type' objects} 1 0.000 0.000 0.000 0.000 ImageSequence.py:19(Iterator) 1 0.000 0.000 0.000 0.000 decimal.py:3748(_ContextManager) 1 0.000 0.000 0.000 0.000 Image.py:2460(register_save_all) 1 0.000 0.000 0.000 0.000 decimal.py:5438(_WorkRep) 1 0.000 0.000 0.000 0.000 {method 'index' of 'str' objects} 1 0.000 0.000 0.000 0.000 TiffTags.py:23(TagInfo) 1 0.000 0.000 0.000 0.000 UserDict.py:35(__getitem__) 1 0.000 0.000 0.000 0.000 ascii.py:20(IncrementalEncoder) 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:515(PngImageFile) 1 0.000 0.000 0.000 0.000 {method 'setter' of 'property' objects} 1 0.000 0.000 0.000 0.000 GimpGradientFile.py:61(GradientFile) 1 0.000 0.000 0.000 0.000 decimal.py:310(Subnormal) 1 0.000 0.000 0.000 0.000 decimal.py:234(DivisionByZero) 1 0.000 0.000 0.000 0.000 {method 'lstrip' of 'str' objects} 1 0.000 0.000 0.000 0.000 {any} 1 0.000 0.000 0.000 0.000 decimal.py:284(InvalidContext) 1 0.000 0.000 0.000 0.000 GimpGradientFile.py:102(GimpGradientFile) 1 0.000 0.000 0.000 0.000 decimal.py:160(DecimalException) 1 0.000 0.000 0.000 0.000 decimal.py:5696(__init__) 1 0.000 0.000 0.000 0.000 PpmImagePlugin.py:59(PpmImageFile) 1 0.000 0.000 0.000 0.000 ascii.py:24(IncrementalDecoder) 2 0.000 0.000 0.000 0.000 {thread.get_ident} 1 0.000 0.000 0.000 0.000 decimal.py:261(DivisionUndefined) 1 0.000 0.000 0.000 0.000 decimal.py:321(Overflow) 1 0.000 0.000 0.000 0.000 decimal.py:224(ConversionSyntax) 1 0.000 0.000 0.000 0.000 decimal.py:183(Clamped) 1 0.000 0.000 0.000 0.000 PngImagePlugin.py:657(_idat) 1 0.000 0.000 0.000 0.000 PaletteFile.py:22(PaletteFile) 1 0.000 0.000 0.000 0.000 ascii.py:34(StreamConverter) 1 0.000 0.000 0.000 0.000 decimal.py:272(Inexact) 1 0.000 0.000 0.000 0.000 decimal.py:250(DivisionImpossible) 3 0.000 0.000 0.000 0.000 {abs} 1 0.000 0.000 0.000 0.000 ascii.py:31(StreamReader) 1 0.000 0.000 0.000 0.000 __init__.py:587(__init__) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 1 0.000 0.000 0.000 0.000 decimal.py:5692(_Log10Memoize) 1 0.000 0.000 0.000 0.000 decimal.py:195(InvalidOperation) 1 0.000 0.000 0.000 0.000 decimal.py:359(Underflow) 1 0.000 0.000 0.000 0.000 BmpImagePlugin.py:211(DibImageFile) 1 0.000 0.000 0.000 0.000 decimal.py:298(Rounded) 1 0.000 0.000 0.000 0.000 {method 'release' of 'thread.lock' objects} 1 0.000 0.000 0.000 0.000 ascii.py:28(StreamWriter) real 0m29.797s user 0m28.404s sys 0m0.376s
Python 3.5.2+
This script requires the Python Imaging Library - http://www.pythonware.com/products/pil/
...
python3-pil is already the newest version (3.3.1-1).
Looks like python3 is no better as it stands on a single thread at least (though, this vm only has one core)
$ time python 'captcha-old.py' --key 'CHANGE_THIS_SECRET!' --output '/tmp/mw-fancycaptcha-1486771866-0b4ca9' --count '100' --dirs '0' --wordlist '/home/reedy/words' --font '/usr/share/fonts/truetype/freefont/FreeMonoBoldOblique.ttf' --blacklist '/home/reedy/badwords' Generating 100 CAPTCHA images separated in 100 image(s) per chunk run by 1 threads... real 0m26.087s user 0m24.716s sys 0m0.364s $ time python3 'captcha-old.py' --key 'CHANGE_THIS_SECRET!' --output '/tmp/mw-fancycaptcha-1486771866-0b4ca9' --count '100' --dirs '0' --wordlist '/home/reedy/words' --font '/usr/share/fonts/truetype/freefont/FreeMonoBoldOblique.ttf' --blacklist '/home/reedy/badwords' Generating 100 CAPTCHA images separated in 100 image(s) per chunk run by 1 threads... real 0m26.845s user 0m25.652s sys 0m0.264s
Really needs testing on a machine with many cores...
$ time python 'captcha-old.py' --key 'CHANGE_THIS_SECRET!' --output '/tmp/mw-fancycaptcha-1486771866-0b4ca9' --count '100' --dirs '0' --wordlist '/home/reedy/words' --font '/usr/share/fonts/truetype/freefont/FreeMonoBoldOblique.ttf' --blacklist '/home/reedy/badwords' --threads 4 Generating 100 CAPTCHA images separated in 25 image(s) per chunk run by 4 threads... real 0m28.953s user 0m27.396s sys 0m0.644s $ time python3 'captcha-old.py' --key 'CHANGE_THIS_SECRET!' --output '/tmp/mw-fancycaptcha-1486771866-0b4ca9' --count '100' --dirs '0' --wordlist '/home/reedy/words' --font '/usr/share/fonts/truetype/freefont/FreeMonoBoldOblique.ttf' --blacklist '/home/reedy/badwords' --threads 4 Generating 100 CAPTCHA images separated in 25 image(s) per chunk run by 4 threads... real 0m27.708s user 0m26.364s sys 0m0.504s
Debian python3-pil package? If so, this isn't the PIL, but instead pillow, iirc. I remember, there was a change to convert the cpatcha.py code from PIL to pillow, as PIL isn't supported anymore.
... Oh no, it wasn't pilow, but a "more current version" of PIL: https://gerrit.wikimedia.org/r/#/c/231157/2
As per the comments after, and also T157888 and the patch in that... I got past that ;)
Hmm, I've a slightly different measure on my 2-core VM:
florian@florian-VirtualBox:/var/www/html/mediawiki/w/extensions/ConfirmEdit$ time python captcha.py --wordlist /usr/share/dict/american-english --font /usr/share/fonts/opentype/noto/NotoSansCJK-Black.ttc --count 100 --key fioegjfrp --output ../../../captchas/ --threads=2 Generating 100 CAPTCHA images separated in 50 image(s) per chunk run by 2 threads... real 0m10.646s user 0m13.780s sys 0m0.648s florian@florian-VirtualBox:/var/www/html/mediawiki/w/extensions/ConfirmEdit$ time python captcha.py --wordlist /usr/share/dict/american-english --font /usr/share/fonts/opentype/noto/NotoSansCJK-Black.ttc --count 100 --key fioegjfrp --output ../../../captchas/ --threads=1 Generating 100 CAPTCHA images separated in 100 image(s) per chunk run by 1 threads... real 0m15.182s user 0m14.676s sys 0m0.216s florian@florian-VirtualBox:/var/www/html/mediawiki/w/extensions/ConfirmEdit$ time python captcha.py --wordlist /usr/share/dict/american-english --font /usr/share/fonts/opentype/noto/NotoSansCJK-Black.ttc --count 100 --key fioegjfrp --output ../../../captchas/ --threads=2 Generating 100 CAPTCHA images separated in 50 image(s) per chunk run by 2 threads... real 0m10.759s user 0m14.180s sys 0m0.528s florian@florian-VirtualBox:/var/www/html/mediawiki/w/extensions/ConfirmEdit$ time python captcha.py --wordlist /usr/share/dict/american-english --font /usr/share/fonts/opentype/noto/NotoSansCJK-Black.ttc --count 100 --key fioegjfrp --output ../../../captchas/ --threads=1 Generating 100 CAPTCHA images separated in 100 image(s) per chunk run by 1 threads... real 0m14.144s user 0m13.680s sys 0m0.184s
Running it now again with 1000 CAPTCHAS to see the difference there.
florian@florian-VirtualBox:/var/www/html/mediawiki/w/extensions/ConfirmEdit$ time python captcha.py --wordlist /usr/share/dict/american-english --font /usr/share/fonts/opentype/noto/NotoSansCJK-Black.ttc --count 1000 --key fioegjfrp --output ../../../captchas/ --threads=2 Generating 1000 CAPTCHA images separated in 500 image(s) per chunk run by 2 threads... real 1m44.139s user 2m24.104s sys 0m5.696s florian@florian-VirtualBox:/var/www/html/mediawiki/w/extensions/ConfirmEdit$ time python captcha.py --wordlist /usr/share/dict/american-english --font /usr/share/fonts/opentype/noto/NotoSansCJK-Black.ttc --count 1000 --key fioegjfrp --output ../../../captchas/ --threads=1 Generating 1000 CAPTCHA images separated in 1000 image(s) per chunk run by 1 threads... real 2m23.425s user 2m21.032s sys 0m1.552s
You'd probably want to use something like multiprocessing instead of threads. Threads really aren't all that useful--they use the same I/O scheduler and have the global interpeter lock. Threads technically have a slightly lower startup cost, but this is really negligible for tasks of any measurable length--most benchmarks you'll find here are pointless.
As best I can tell you're not actually needing to share any memory between these processes--everything is passed as a parameter to your function--you'd probably see a drastic improvement in moving from Thread() to Pool()
With multiprocessing:
time python captcha.py --font=/usr/share/fonts/truetype/freefont/FreeSans.ttf --wordlist=/usr/share/dict/words --key=FOO --output=../../../captchas --threads=2 --count=1000 Generating 1000 CAPTCHA images separated in 500 image(s) per chunk run by 2 threads... real 0m57.557s user 1m48.760s sys 0m2.036s
Without:
time python captcha.py --font=/usr/share/fonts/truetype/freefont/FreeSans.ttf --wordlist=/usr/share/dict/words --key=FOO --output=../../../captchas --threads=1 --count=1000 Generating 1000 CAPTCHA images separated in 1000 image(s) per chunk run by 1 threads... real 1m47.056s user 1m45.784s sys 0m0.764s
So... That looks like a decent improvement. Results confirmed locally
reedy@ubuntu64-web-esxi:/var/www/wiki/mediawiki/extensions/ConfirmEdit$ time python captcha.py --font=/usr/share/fonts/truetype/freefont/FreeSans.ttf --wordlist=/usr/share/dict/words --key=FOO --output=/tmp/captchas --count=1000 real 5m1.770s user 5m0.188s sys 0m1.168s
After pulling the patch...
reedy@ubuntu64-web-esxi:/var/www/wiki/mediawiki/extensions/ConfirmEdit$ time python captcha.py --font=/usr/share/fonts/truetype/freefont/FreeSans.ttf --wordlist=/usr/share/dict/words --key=FOO --output=/tmp/captchas --threads=1 --count=1000 Generating 1000 CAPTCHA images separated in 1000 image(s) per chunk run by 1 threads... real 5m3.015s user 5m0.752s sys 0m1.920s reedy@ubuntu64-web-esxi:/var/www/wiki/mediawiki/extensions/ConfirmEdit$ time python captcha.py --font=/usr/share/fonts/truetype/freefont/FreeSans.ttf --wordlist=/usr/share/dict/words --key=FOO --output=/tmp/captchas --threads=2 --count=1000 Generating 1000 CAPTCHA images separated in 500 image(s) per chunk run by 2 threads... real 2m54.467s user 5m40.848s sys 0m5.144s
Change 337057 merged by jenkins-bot:
[mediawiki/extensions/ConfirmEdit@master] Add threads parameter to captcha.py for multithread CAPTCHA generation