Rust高效字符串压缩库fsst-rs的使用,fsst-rs提供高性能字符串压缩与解压缩功能

Rust高效字符串压缩库fsst-rs的使用

FSST Logo

fsst-rs是一个纯Rust实现、零依赖的FSST字符串压缩算法库。

FSST是一种专为数据库系统设计的字符串压缩算法,由Peter Boncz、Thomas Neumann和Viktor Leis设计。它提供1-3GB/秒的字符串压缩和解压速度,压缩率与LZ4相当或更好。

安装

在项目目录中运行以下Cargo命令:

cargo add fsst-rs

或在Cargo.toml中添加:

fsst-rs = "0.5.3"

使用示例

以下是一个完整的fsst-rs使用示例:

use fsst_rs::{Encoder, Decoder};

fn main() {
    // 准备要压缩的字符串样本
    let samples = vec![
        "This is the first sample string",
        "This is the second sample string",
        "Yet another string to be compressed",
    ];
    
    // 创建编码器并训练压缩字典
    let encoder = Encoder::train(&samples).unwrap();
    
    // 压缩单个字符串
    let text = "This string will be compressed";
    let compressed = encoder.compress(text);
    
    // 创建解码器
    let decoder = Decoder::from(&encoder);
    
    // 解压数据
    let decompressed = decoder.decompress(&compressed).unwrap();
    
    // 验证结果
    assert_eq!(text, decompressed);
    println!("Original: {}", text);
    println!("Decompressed: {}", decompressed);
}

完整示例

以下是一个更完整的fsst-rs使用示例,包含批量压缩和性能测试:

use fsst_rs::{Encoder, Decoder};
use std::time::Instant;

fn main() {
    // 准备大量测试数据
    let samples: Vec<String> = (0..1000)
        .map(|i| format!("This is sample string number {}", i))
        .collect();
    
    // 训练编码器
    let train_start = Instant::now();
    let encoder = Encoder::train(&samples).unwrap();
    println!("训练时间: {:?}", train_start.elapsed());
    
    // 批量压缩
    let compress_start = Instant::now();
    let compressed: Vec<Vec<u8>> = samples
        .iter()
        .map(|s| encoder.compress(s))
        .collect();
    println!("压缩时间: {:?}", compress_start.elapsed());
    
    // 创建解码器
    let decoder = Decoder::from(&encoder);
    
    // 批量解压并验证
    let decompress_start = Instant::now();
    for (i, data) in compressed.iter().enumerate() {
        let decompressed = decoder.decompress(data).unwrap();
        assert_eq!(&samples[i], &decompressed);
    }
    println!("解压时间: {:?}", decompress_start.elapsed());
    
    // 打印压缩率
    let original_size: usize = samples.iter().map(|s| s.len()).sum();
    let compressed_size: usize = compressed.iter().map(|v| v.len()).sum();
    println!("压缩率: {:.2}%", (compressed_size as f64 / original_size as f64) * 100.0);
}

特性说明

  1. 高性能:提供1-3GB/sec的压缩和解压速度
  2. 高压缩率:压缩率与LZ4相当或更好
  3. 数据库优化:专为数据库系统设计
  4. 纯Rust实现:零依赖

注意事项

  • 当前实现仍在进行中,尚未达到生产就绪状态,请谨慎使用
  • 目前仅支持小端架构,没有支持大端目标的计划

许可证

Apache-2.0


1 回复

Rust高效字符串压缩库fsst-rs的使用

介绍

fsst-rs是Rust语言对FSST(Fast Static Symbol Table)压缩算法的实现,专门针对字符串数据提供高性能的压缩与解压缩功能。FSST算法特别适合处理大量短字符串的场景,如数据库中的字符串列、日志消息等。

主要特点:

  • 极高的压缩和解压速度
  • 针对短字符串优化的压缩率
  • 零内存分配的压缩/解压过程
  • 支持随机访问压缩数据

安装方法

在Cargo.toml中添加依赖:

[dependencies]
fsst = "0.1"

基本使用方法

压缩字符串

use fsst::{Encoder, Decoder};

fn main() {
    // 准备要压缩的字符串
    let input = "This is a sample string for FSST compression. FSST works well with short strings.";
    
    // 创建编码器
    let encoder = Encoder::new();
    
    // 压缩字符串
    let compressed = encoder.compress(input);
    
    println!("Original size: {} bytes", input.len());
    println!("Compressed size: {} bytes", compressed.len());
}

解压缩字符串

use fsst::{Encoder, Decoder};

fn main() {
    let input = "This is a sample string for FSST compression.";
    
    let encoder = Encoder::new();
    let compressed = encoder.compress(input);
    
    // 创建解码器(需要与编码器相同的符号表)
    let decoder = Decoder::from_encoder(&encoder);
    
    // 解压缩
    let decompressed = decoder.decompress(&compressed).unwrap();
    
    assert_eq!(input, decompressed);
    println!("Decompressed: {}", decompressed);
}

批量处理字符串

fsst-rs特别适合批量处理字符串:

use fsst::{Encoder, Decoder};

fn main() {
    let strings = vec![
        "first string",
        "second string",
        "third string",
        "another example",
        "FSST compression"
    ];
    
    let encoder = Encoder::new();
    let decoder = Decoder::from_encoder(&encoder);
    
    // 压缩所有字符串
    let compressed: Vec<_> = strings.iter()
        .map(|s| encoder.compress(s))
        .collect();
    
    // 解压缩所有字符串
    let decompressed: Vec<_> = compressed.iter()
        .map(|c| decoder.decompress(c).unwrap())
        .collect();
    
    assert_eq!(strings, decompressed);
}

高级用法:自定义符号表

对于特定领域的字符串,可以训练自定义符号表提高压缩率:

use fsst::{EncoderBuilder, Decoder};

fn main() {
    // 训练数据
    let training_data = vec![
        "error: file not found",
        "warning: deprecated API",
        "info: connection established",
        "debug: sending packet",
        "error: permission denied"
    ];
    
    // 使用训练数据构建编码器
    let encoder = EncoderBuilder::new()
        .train(&training_data)
        .build();
    
    // 现在编码器针对日志消息优化过
    let compressed = encoder.compress("error: timeout reached");
    
    let decoder = Decoder::from_encoder(&encoder);
    let decompressed = decoder.decompress(&compressed).unwrap();
    
    println!("{}", decompressed);
}

完整示例demo

以下是一个完整的fsst-rs使用示例,展示了从安装到压缩解压缩的完整流程:

// 在Cargo.toml中添加依赖: fsst = "0.1"

use fsst::{Encoder, Decoder, EncoderBuilder};

fn main() {
    // 示例1: 基本压缩解压
    basic_compression();
    
    // 示例2: 批量处理字符串
    batch_processing();
    
    // 示例3: 自定义符号表
    custom_symbol_table();
}

fn basic_compression() {
    println!("=== 基本压缩解压示例 ===");
    
    let text = "FSST是一个非常高效的短字符串压缩算法";
    
    // 创建编码器
    let encoder = Encoder::new();
    // 压缩字符串
    let compressed = encoder.compress(text);
    
    println!("原始大小: {}字节", text.len());
    println!("压缩后大小: {}字节", compressed.len());
    
    // 创建解码器
    let decoder = Decoder::from_encoder(&encoder);
    // 解压缩
    let decompressed = decoder.decompress(&compressed).unwrap();
    
    assert_eq!(text, decompressed);
    println!("解压结果: {}", decompressed);
    println!();
}

fn batch_processing() {
    println!("=== 批量处理示例 ===");
    
    let data = vec![
        "第一条测试数据",
        "第二条测试数据",
        "第三条测试数据",
        "第四条测试数据",
    ];
    
    let encoder = Encoder::new();
    let decoder = Decoder::from_encoder(&encoder);
    
    // 批量压缩
    let compressed: Vec<_> = data.iter()
        .map(|s| encoder.compress(s))
        .collect();
    
    // 计算压缩率
    let original_size: usize = data.iter().map(|s| s.len()).sum();
    let compressed_size: usize = compressed.iter().map(|c| c.len()).sum();
    println!("总压缩率: {:.2}%", (compressed_size as f32 / original_size as f32) * 100.0);
    
    // 批量解压
    let decompressed: Vec<_> = compressed.iter()
        .map(|c| decoder.decompress(c).unwrap())
        .collect();
    
    assert_eq!(data, decompressed);
    println!("批量解压验证成功");
    println!();
}

fn custom_symbol_table() {
    println!("=== 自定义符号表示例 ===");
    
    // 训练数据(特定领域的日志消息)
    let training_data = vec![
        "ERROR: 文件未找到",
        "WARNING: 内存不足",
        "INFO: 连接已建立",
        "DEBUG: 发送数据包",
        "ERROR: 权限拒绝"
    ];
    
    // 使用训练数据构建优化后的编码器
    let encoder = EncoderBuilder::new()
        .train(&training_data)
        .build();
    
    // 测试数据
    let test_message = "ERROR: 超时发生";
    let compressed = encoder.compress(test_message);
    
    println!("测试消息: {}", test_message);
    println!("压缩后大小: {}字节", compressed.len());
    
    // 解压缩
    let decoder = Decoder::from_encoder(&encoder);
    let decompressed = decoder.decompress(&compressed).unwrap();
    
    assert_eq!(test_message, decompressed);
    println!("解压结果: {}", decompressed);
}

性能提示

  1. 对于大量相似结构的字符串,使用训练过的编码器能获得更好的压缩率
  2. 编码器创建成本较高,应复用同一个编码器处理多个字符串
  3. 解压速度通常比压缩速度更快

fsst-rs是处理大量短字符串时的理想选择,特别是在需要快速压缩解压且对压缩率有一定要求的场景下表现优异。

回到顶部