You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In general terms, most of the low hanging fruit was done years ago.
What's left is things that become possible with heavy refactoring (though the gains are hard to predict in some cases) and compiling parts with Cython (though to get decent gains there you'll likely have to refactor to take out some new bottlenecks, I think).
Not quite sure what to make of the fact that 7 seconds are spent insideHTMLTokenizer.__iter__. It doesn't seem like it has very much to do, just calling out to the state functions that do most of the work. Maybe it would help to cythonize this?
7 seconds spent inside HTMLParser.mainLoop also seems a bit strange. I haven't done a whole lot of digging into that.
Another 7 seconds is spent inside HTMLTokenizer.tagNameState. Thinking that could also be flattened/cythonized.
The tokenizer represents tokens as dictionaries. If a Token class were created, it could be cythonized so that adding tokens to the queue could be done without calling anything.
Yet another 7 seconds is spent in HTMLInputStream.char. It's pretty damn simple, so a good candidate for cythonization. (if that's a word)
Honestly if you are going to have a dependency like Cython a much, much more effective approach would be to write python bindings for html5ever. That will give you lxml-comparable speed with equal or better spec conformance compared to html5lib.
@tbodt the "oddly" small functions all spend the majority of their time doing dict lookups, and Cython won't help that.
Gumbo has some means of building a Python tree through html5lib's treebuilders, but that's probably still needlessly expensive given the cost of construction the tree (especially versus lxml and cElementTree which don't iterate through the tree in any way in Python code), which might make it better than html5ever, but it doesn't support everything html5lib does (non-UTF-8 encodings are a big one), which html5ever has some support for.
Is there a recommended way to profile html5lib? The benchmarks are useful for confirming whether a change/refactor has made an improvement, but it's tricky to figure out where to focus on without having a recommended profiler.
Is there a recommended way to profile html5lib? The benchmarks are useful for confirming whether a change/refactor has made an improvement, but it's tricky to figure out where to focus on without having a recommended profiler.
For #493 I used a mixture of vmprof and py-spy, both of which are sampling profilers, and did some based on the things in the benchmarks directory and some from profiling entire applications using html5lib (which, e.g., showed up the cost of constructing the parser objects).
Brilliant, thanks @gsnedders. Unlikely I'll find anything that hasn't been examined already, but keen to figure out a good process to investigate with.
@jayaddison There's certainly plenty of places where there are potential gains: there's a bunch of places around SVG and MathML in HTML where we could do things quicker, but the comparative rarity of it means it's never been a priority; most of my attention in recent years has been kinda focused on the parser and etree treebuilder, and anything outside of that probably hasn't got much interest in a while. That all said, I hope to land something along the lines of #445, using Cython in Pure Python mode for the input stream and tokenizer, which should give a pretty significant speed-up.
Anything I could use a few spare cycles to help with there? (I saw #24 and figured that might have decent impact, but as I'm fairly new to the codebase it might take a little while)
#24 won't make much impact till it's using Cython I suspect? Also when the parser needs updated to be up-to-date with the spec there's probably not too much point in spending effort there. But no, there's not a huge amount worthwhile doing IMO?
Activity
gsnedders commentedon Feb 6, 2017
In general terms, most of the low hanging fruit was done years ago.
What's left is things that become possible with heavy refactoring (though the gains are hard to predict in some cases) and compiling parts with Cython (though to get decent gains there you'll likely have to refactor to take out some new bottlenecks, I think).
tbodt commentedon Feb 6, 2017
I did a profile on the input
'<tag></tag>'*1000000. Here's the top few lines of profiling output, which account for 99.7 percent of execution time:Observations:
Not quite sure what to make of the fact that 7 seconds are spent inside
HTMLTokenizer.__iter__. It doesn't seem like it has very much to do, just calling out to the state functions that do most of the work. Maybe it would help to cythonize this?7 seconds spent inside
HTMLParser.mainLoopalso seems a bit strange. I haven't done a whole lot of digging into that.Another 7 seconds is spent inside
HTMLTokenizer.tagNameState. Thinking that could also be flattened/cythonized.The tokenizer represents tokens as dictionaries. If a Token class were created, it could be cythonized so that adding tokens to the queue could be done without calling anything.
Yet another 7 seconds is spent in
HTMLInputStream.char. It's pretty damn simple, so a good candidate for cythonization. (if that's a word)Anyone have anything to add?
jgraham commentedon Feb 6, 2017
Honestly if you are going to have a dependency like Cython a much, much more effective approach would be to write python bindings for html5ever. That will give you lxml-comparable speed with equal or better spec conformance compared to html5lib.
tbodt commentedon Feb 6, 2017
@jgraham I did not know about html5ever. That's totally what I'm going to be using instead of html5lib. Thanks a lot!
gsnedders commentedon Feb 6, 2017
@tbodt the "oddly" small functions all spend the majority of their time doing dict lookups, and Cython won't help that.
Gumbo has some means of building a Python tree through html5lib's treebuilders, but that's probably still needlessly expensive given the cost of construction the tree (especially versus lxml and cElementTree which don't iterate through the tree in any way in Python code), which might make it better than html5ever, but it doesn't support everything html5lib does (non-UTF-8 encodings are a big one), which html5ever has some support for.
gsnedders commentedon Feb 9, 2017
Also, to note, Python 3.7 is on some benchmarks of html5lib 25% quicker than Python 2.7.
jayaddison commentedon Dec 16, 2020
Is there a recommended way to profile
html5lib? The benchmarks are useful for confirming whether a change/refactor has made an improvement, but it's tricky to figure out where to focus on without having a recommended profiler.gsnedders commentedon Dec 16, 2020
For #493 I used a mixture of vmprof and py-spy, both of which are sampling profilers, and did some based on the things in the benchmarks directory and some from profiling entire applications using html5lib (which, e.g., showed up the cost of constructing the parser objects).
jayaddison commentedon Dec 16, 2020
Brilliant, thanks @gsnedders. Unlikely I'll find anything that hasn't been examined already, but keen to figure out a good process to investigate with.
gsnedders commentedon Dec 16, 2020
@jayaddison There's certainly plenty of places where there are potential gains: there's a bunch of places around SVG and MathML in HTML where we could do things quicker, but the comparative rarity of it means it's never been a priority; most of my attention in recent years has been kinda focused on the parser and etree treebuilder, and anything outside of that probably hasn't got much interest in a while. That all said, I hope to land something along the lines of #445, using Cython in Pure Python mode for the input stream and tokenizer, which should give a pretty significant speed-up.
jayaddison commentedon Dec 16, 2020
Anything I could use a few spare cycles to help with there? (I saw #24 and figured that might have decent impact, but as I'm fairly new to the codebase it might take a little while)
gsnedders commentedon Dec 16, 2020
#24 won't make much impact till it's using Cython I suspect? Also when the parser needs updated to be up-to-date with the spec there's probably not too much point in spending effort there. But no, there's not a huge amount worthwhile doing IMO?
jayaddison commentedon Dec 17, 2020
Okie doke. Glad to help out with anything performance-related if & when that'd be useful.