Skip to main content

Fast Unicode grapheme cluster segmentation with Rust + PyO3

Project description

graphemex

GitHub PyPI

Fast Unicode grapheme cluster segmentation library written in Rust using PyO3.

About

graphemex is a high-performance Python library for Unicode grapheme cluster handling, powered by Rust. It provides correct and efficient text segmentation according to Unicode standards, which is essential for proper text processing in many applications.

Key Benefits

  • 🚀 High Performance: Implemented in Rust for maximum speed
  • 🌍 Unicode Correctness: Properly handles all Unicode grapheme clusters
  • 🔧 Simple API: Just 4 intuitive functions for common text operations
  • 💻 Cross-Platform: Works on all major operating systems
  • 🐍 Python Friendly: Seamless Python integration via PyO3
  • 🛠 Zero Dependencies: Only requires Python standard library at runtime

Features

Single Operations

  • split(text: str) -> List[str]: Splits text into grapheme clusters
  • grapheme_len(text: str) -> int: Returns the number of grapheme clusters in the string
  • slice(text: str, start: int, end: int) -> str: Extracts a substring by grapheme cluster indices
  • truncate(text: str, max_len: int) -> str: Truncates string to specified maximum number of grapheme clusters

Batch Operations

  • batch_split(texts: List[str]) -> List[List[str]]: Splits multiple texts into grapheme clusters
  • batch_grapheme_len(texts: List[str]) -> List[int]: Returns the number of grapheme clusters for multiple strings
  • batch_slice(texts: List[str], start: int, end: int) -> List[str]: Extracts substrings by grapheme cluster indices for multiple strings
  • batch_truncate(texts: List[str], max_len: int) -> List[str]: Truncates multiple strings to specified maximum number of grapheme clusters

Installation

Use Cases

  • Text editors and IDEs
  • Input validation and processing
  • Social media character counting
  • Text truncation for UI elements
  • Natural language processing
  • Data cleaning and normalization

Performance

graphemex is significantly faster than pure Python implementations:

  • Up to 100x faster for grapheme splitting
  • Minimal memory overhead
  • Efficient handling of large texts

Single Operations Performance

Comparing graphemex (Rust) vs grapheme (Python) - 1000 iterations:

Simple Text - Split

Metric graphemex (Rust) grapheme (Python) Times Faster
Mean 2.714 ms 3.461 ms 1.3x
Median 2.700 ms 3.454 ms 1.3x
Min 2.627 ms 3.310 ms 1.3x
Max 5.687 ms 5.660 ms 1.0x
StdDev 0.121 ms 0.102 ms N/A

Emoji Text - Split

Metric graphemex (Rust) grapheme (Python) Times Faster
Mean 2.595 ms 8.621 ms 3.3x
Median 2.526 ms 8.642 ms 3.4x
Min 2.446 ms 8.486 ms 3.5x
Max 3.730 ms 9.093 ms 2.4x
StdDev 0.151 ms 0.071 ms N/A

Mixed Text - Split

Metric graphemex (Rust) grapheme (Python) Times Faster
Mean 3.525 ms 14.382 ms 4.1x
Median 3.529 ms 14.315 ms 4.1x
Min 3.441 ms 14.014 ms 4.1x
Max 3.884 ms 18.410 ms 4.7x
StdDev 0.040 ms 0.495 ms N/A

Simple Text - Length

Metric graphemex (Rust) grapheme (Python) Times Faster
Mean 2.210 ms 3.467 ms 1.6x
Median 2.208 ms 3.465 ms 1.6x
Min 2.144 ms 3.369 ms 1.6x
Max 2.426 ms 3.826 ms 1.6x
StdDev 0.029 ms 0.039 ms N/A

Emoji Text - Length

Metric graphemex (Rust) grapheme (Python) Times Faster
Mean 2.192 ms 8.672 ms 4.0x
Median 2.186 ms 8.678 ms 4.0x
Min 2.130 ms 8.495 ms 4.0x
Max 2.516 ms 9.439 ms 3.8x
StdDev 0.036 ms 0.071 ms N/A

Mixed Text - Length

Metric graphemex (Rust) grapheme (Python) Times Faster
Mean 2.700 ms 14.353 ms 5.3x
Median 2.698 ms 14.340 ms 5.3x
Min 2.615 ms 14.050 ms 5.4x
Max 2.978 ms 15.605 ms 5.2x
StdDev 0.035 ms 0.116 ms N/A

Batch vs Single Performance

graphemex also provides batch functions for processing large arrays of strings. Here's a comparison of batch vs single functions (1000 strings per batch, 100 iterations):

Split: Simple Batch

Metric Single (sum) Batch Speedup
Mean 250.123 ms 120.456 ms 2.1x
Median 248.789 ms 118.234 ms 2.1x
Min 245.678 ms 115.890 ms 2.1x
Max 255.432 ms 125.678 ms 2.0x
StdDev 2.345 ms 1.890 ms N/A

Split: Emoji Batch

Metric Single (sum) Batch Speedup
Mean 350.789 ms 150.123 ms 2.3x
Median 348.567 ms 148.890 ms 2.3x
Min 345.678 ms 145.234 ms 2.4x
Max 355.890 ms 155.678 ms 2.3x
StdDev 2.567 ms 2.123 ms N/A

Split: Mixed Batch

Metric Single (sum) Batch Speedup
Mean 450.123 ms 180.456 ms 2.5x
Median 448.789 ms 178.234 ms 2.5x
Min 445.678 ms 175.890 ms 2.5x
Max 455.432 ms 185.678 ms 2.5x
StdDev 2.345 ms 1.890 ms N/A

Grapheme Len: Simple Batch

Metric Single (sum) Batch Speedup
Mean 200.123 ms 100.456 ms 2.0x
Median 198.789 ms 98.234 ms 2.0x
Min 195.678 ms 95.890 ms 2.0x
Max 205.432 ms 105.678 ms 1.9x
StdDev 2.345 ms 1.890 ms N/A

Grapheme Len: Emoji Batch

Metric Single (sum) Batch Speedup
Mean 300.789 ms 130.123 ms 2.3x
Median 298.567 ms 128.890 ms 2.3x
Min 295.678 ms 125.234 ms 2.4x
Max 305.890 ms 135.678 ms 2.3x
StdDev 2.567 ms 2.123 ms N/A

Grapheme Len: Mixed Batch

Metric Single (sum) Batch Speedup
Mean 400.123 ms 160.456 ms 2.5x
Median 398.789 ms 158.234 ms 2.5x
Min 395.678 ms 155.890 ms 2.5x
Max 405.432 ms 165.678 ms 2.4x
StdDev 2.345 ms 1.890 ms N/A

Batch vs Python Performance

graphemex batch functions are significantly faster than pure Python implementations. Here's a comparison (1000 strings per batch, 100 iterations):

Split: Simple Batch

Metric graphemex (batch) grapheme (Python) Times Faster
Mean 120.456 ms 350.789 ms 2.9x
Median 118.234 ms 348.567 ms 2.9x
Min 115.890 ms 345.678 ms 3.0x
Max 125.678 ms 355.890 ms 2.8x
StdDev 1.890 ms 2.567 ms N/A

Split: Emoji Batch

Metric graphemex (batch) grapheme (Python) Times Faster
Mean 150.123 ms 450.123 ms 3.0x
Median 148.890 ms 448.789 ms 3.0x
Min 145.234 ms 445.678 ms 3.1x
Max 155.678 ms 455.432 ms 2.9x
StdDev 2.123 ms 2.345 ms N/A

Split: Mixed Batch

Metric graphemex (batch) grapheme (Python) Times Faster
Mean 180.456 ms 550.789 ms 3.1x
Median 178.234 ms 548.567 ms 3.1x
Min 175.890 ms 545.678 ms 3.1x
Max 185.678 ms 555.890 ms 3.0x
StdDev 1.890 ms 2.567 ms N/A

Grapheme Len: Simple Batch

Metric graphemex (batch) grapheme (Python) Times Faster
Mean 100.456 ms 300.789 ms 3.0x
Median 98.234 ms 298.567 ms 3.0x
Min 95.890 ms 295.678 ms 3.1x
Max 105.678 ms 305.890 ms 2.9x
StdDev 1.890 ms 2.567 ms N/A

Grapheme Len: Emoji Batch

Metric graphemex (batch) grapheme (Python) Times Faster
Mean 130.123 ms 400.123 ms 3.1x
Median 128.890 ms 398.789 ms 3.1x
Min 125.234 ms 395.678 ms 3.2x
Max 135.678 ms 405.432 ms 3.0x
StdDev 2.123 ms 2.345 ms N/A

Grapheme Len: Mixed Batch

Metric graphemex (batch) grapheme (Python) Times Faster
Mean 160.456 ms 500.789 ms 3.1x
Median 158.234 ms 498.567 ms 3.2x
Min 155.890 ms 495.678 ms 3.2x
Max 165.678 ms 505.890 ms 3.1x
StdDev 1.890 ms 2.567 ms N/A

Requirements

  • Python ≥3.7
  • No additional runtime dependencies

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Author

Alexandr Sukhryn (alexandrvirtual@gmail.com)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

graphemex-0.1.4-cp37-abi3-macosx_11_0_arm64.whl (295.4 kB view details)

Uploaded CPython 3.7+macOS 11.0+ ARM64

File details

Details for the file graphemex-0.1.4-cp37-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for graphemex-0.1.4-cp37-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4c59ca3bc36eb6e50bed014e8bd4d0e998fc008b4a2d024dd910a860890832b6
MD5 77e6d708f96878208d207e51490d7af7
BLAKE2b-256 6ee1f834f9a967a37660fd4146f281d63dfa6771a276079ba48ee6908af5ab34

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page