While debugging some slow scraping recently I realized that the vast majority of the time was spent in TagSoup.parseTags. Naively swapping to the fast-tagsoup package results in a ~20x speedup for the case that I was debugging.
Example of using the fast-tagsoup parser (note that it only works with strict ByteStrings):
import Text.HTML.Scalpel.Core
import qualified Text.HTML.TagSoup as TagSoup
import qualified Text.HTML.TagSoup.Fast as TagSoupFast
import qualified Data.ByteString as BS
scrapeByteStringT :: Monad m => BS.ByteString -> ScraperT BS.ByteString m a -> m (Maybe a)
scrapeByteStringT html scraper = scrapeT scraper tags
where
tags = TagSoupFast.parseTags html
Given this ridiculous speedup, it probably makes sense to try and make this the default HTML parser for scalpel. Doing that would require figuring out how to work this into the existing API where the scraper class is parameterized by the underlying string type.
Maybe we do a breaking API change and finally do away with all the StringLike code once and for all.
While debugging some slow scraping recently I realized that the vast majority of the time was spent in
TagSoup.parseTags
. Naively swapping to the fast-tagsoup package results in a ~20x speedup for the case that I was debugging.Example of using the
fast-tagsoup
parser (note that it only works with strict ByteStrings):Given this ridiculous speedup, it probably makes sense to try and make this the default HTML parser for scalpel. Doing that would require figuring out how to work this into the existing API where the scraper class is parameterized by the underlying string type.
Maybe we do a breaking API change and finally do away with all the
StringLike
code once and for all.