Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ using a 64-bit 2.6 GHz Intel Core i9:

Running tokenization with PyPy is about 3x faster than with CPython.

Version 3.6.3 reduces the cost of origin tracking by materializing
`origin_spans` lazily. On `test/toktest_large.txt` (573 KB, about 149k tokens),
this improved CPython tokenization throughput by roughly 8-12% and reduced
peak memory by about 9 MB when retaining the token list.
Version 3.6.4 avoids a redundant whitespace-tokenization pass for normal input,
while retaining the additional pass when HTML escape replacement can introduce
whitespace. On `test/toktest_large.txt` (573 KB, about 149k tokens), this reduces
CPython tokenization time by roughly 20% compared with version 3.6.3, with
identical token text, values, original text and origin spans.

## Deep vs. shallow tokenization

Expand Down Expand Up @@ -716,6 +717,11 @@ can be found in the file `test/toktest_normal_gold_expected.txt`.

## Changelog

* Version 3.6.4: Improved tokenization performance by constructing rough tokens
directly with their lazy origin offsets and skipping a redundant second
whitespace-tokenization pass unless HTML escape replacement is enabled. This
reduces CPython tokenization time by roughly 20% on the large test corpus while
preserving token output and origin tracking.
* Version 3.6.3: Improved origin tracking performance by materializing
`origin_spans` lazily, while preserving the public token API and index
behavior. Fixed validation edge cases in `valid_ssn()`, Roman numeral
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "tokenizer"
version = "3.6.3"
version = "3.6.4"
description = "A fast, compact pure-Python tokenizer for Icelandic text with sentence segmentation"
authors = [{ name = "Miðeind ehf.", email = "mideind@mideind.is" }]
maintainers = [{ name = "Vilhjálmur Þorsteinsson", email = "vt@mideind.is" }]
Expand Down
24 changes: 19 additions & 5 deletions src/tokenizer/tokenizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1518,7 +1518,16 @@ def generate_rough_tokens_from_txt(text: str) -> Iterator[Tok]:
match = ROUGH_TOKEN_REGEX.match(text, pos)
assert match is not None
match_span = match.span(ROUGH_TOKEN_REGEX_ENTIRE_MATCH)
tok = Tok.from_txt(text[match_span[SPAN_START] : match_span[SPAN_END]])
whitespace_span = match.span(ROUGH_TOKEN_REGEX_WHITE_SPACE_GROUP)
token_span = match.span(ROUGH_TOKEN_REGEX_TOKEN_GROUP)
tok = Tok(
TOK.RAW,
text[token_span[SPAN_START] : token_span[SPAN_END]],
None,
text[match_span[SPAN_START] : match_span[SPAN_END]],
lazy_origin_spans=True,
lazy_origin_offset=whitespace_span[SPAN_END] - match_span[SPAN_START],
)
pos = match_span[SPAN_END]
yield tok

Expand Down Expand Up @@ -1643,10 +1652,15 @@ def generate_raw_tokens(
if replace_html_escapes:
# Replace HTML escapes: 'á' -> 'á'
tok = html_replacement(tok)
# HTML escapes and unicode may contain whitespace characters
# e.g. Em space ' ' and non-breaking space ' '
# Here we split those tokens into multiple tokens.
for small_tok in generate_rough_tokens_from_tok(tok):
# HTML escapes may introduce whitespace characters, e.g. Em
# space ' ' and non-breaking space ' '. Only that
# optional replacement requires another rough-token pass.
small_tokens: Iterable[Tok] = (
generate_rough_tokens_from_tok(tok)
if replace_html_escapes
else (tok,)
)
for small_tok in small_tokens:
if small_tok.txt == "":
# There was whitespace at the end of the last token.
# We do not want to yield a token with empty text
Expand Down
Loading