Rust哈希计算库ch_cityhash102的使用:高性能CityHash算法实现与字符串哈希优化

Rust哈希计算库ch_cityhash102的使用:高性能CityHash算法实现与字符串哈希优化

以下是内容中提供的示例代码:

use ch_cityhash102::{cityhash64, cityhash128};

fn main() {
    // 要计算哈希的字符串
    let input = "Hello, world!";
    
    // 计算64位CityHash
    let hash64 = cityhash64(input.as_bytes());
    println!("64-bit CityHash of '{}': {:x}", input, hash64);
    
    // 计算128位CityHash
    let hash128 = cityhash128(input.as_bytes());
    println!("128-bit CityHash of '{}': {:x?}", input, hash128);
    
    // 比较不同输入的哈希值
    let input2 = "Hello, World!";
    let hash64_2 = cityhash64(input2.as_bytes());
    println!("64-bit CityHash of '{}': {:x}", input2, hash64_2);
    
    // 检查哈希冲突
    if hash64 != hash64_2 {
        println!("Different inputs produce different hashes (as expected)");
    }
}

完整示例demo

以下是一个更完整的示例,展示了更多使用场景:

use ch_cityhash102::{cityhash64, cityhash128};

fn main() {
    // 示例1: 基本字符串哈希
    let input1 = "Rust编程语言";
    let hash64_1 = cityhash64(input1.as_bytes());
    let hash128_1 = cityhash128(input1.as_bytes());
    println!("示例1 - 64位哈希: {:x}", hash64_1);
    println!("示例1 - 128位哈希: {:x?}", hash128_1);

    // 示例2: 不同大小写字符串的哈希对比
    let input2_lower = "clickhouse";
    let input2_upper = "CLICKHOUSE";
    let hash_lower = cityhash64(input2_lower.as_bytes());
    let hash_upper = cityhash64(input2_upper.as_bytes());
    println!("示例2 - 小写哈希: {:x}", hash_lower);
    println!("示例2 - 大写哈希: {:x}", hash_upper);

    // 示例3: 长字符串哈希性能测试
    let input3 = "这是一个较长的字符串用于测试CityHash算法对长文本的处理性能,算法会自动分块处理以提高效率。";
    let start = std::time::Instant::now();
    let hash64_3 = cityhash64(input3.as_bytes());
    let duration = start.elapsed();
    println!("示例3 - 长文本64位哈希: {:x}", hash64_3);
    println!("示例3 - 计算耗时: {:?}", duration);

    // 示例4: 字节数组哈希
    let bytes: [u8; 5] = [0xDE, 0xAD, 0xBE, 0xEF, 0x00];
    let hash_bytes = cityhash64(&bytes);
    println!("示例4 - 字节数组哈希: {:x}", hash_bytes);

    // 示例5: 哈希冲突测试
    let inputs = ["a", "b", "c", "d", "e"];
    let mut hashes = std::collections::HashSet::new();
    for input in &inputs {
        let hash = cityhash64(input.as_bytes());
        hashes.insert(hash);
    }
    println!("示例5 - 测试{}个不同输入,产生{}个唯一哈希", inputs.len(), hashes.len());
}

性能优化建议

  1. 对于短字符串(小于32字节),CityHash算法已经进行了优化
  2. 对于长字符串,算法会自动选择最优的分块处理方式
  3. 避免频繁创建临时字节数组,尽量直接使用已有的字节切片

注意事项

  • 该实现与ClickHouse的哈希计算完全兼容
  • 算法结果是确定性的,相同的输入总是产生相同的输出
  • 这不是加密哈希函数,不适用于安全敏感场景

这个库特别适合需要与ClickHouse交互或需要高性能字符串哈希计算的Rust应用程序。


1 回复

Rust哈希计算库ch_cityhash102使用指南

概述

ch_cityhash102是一个Rust实现的CityHash算法库,提供了高性能的字符串哈希计算功能。CityHash是Google开发的一系列非加密哈希函数,针对字符串数据进行了优化,特别适合哈希表等数据结构使用。

特性

  • 高性能:针对现代CPU架构优化
  • 低碰撞率:提供良好的哈希分布
  • 支持多种输入类型:字符串、字节切片等
  • 无依赖:纯Rust实现

使用方法

添加依赖

在Cargo.toml中添加:

[dependencies]
ch_cityhash102 = "0.1"

基本使用

use ch_cityhash102::city_hash_102_128;

fn main() {
    let data = "hello world";
    let hash = city_hash_102_128(data.as_bytes());
    
    println!("128-bit hash of '{}': {:?}", data, hash);
}

64位哈希

use ch_cityhash102::city_hash_102_64;

let hash = city_hash_102_64(b"example data");
println!("64-bit hash: {}", hash);

128位哈希

use ch_cityhash102::city_hash_102_128;

let hash = city_hash_102_128(b"example data");
println!("128-bit hash: {:?}", hash);  // 输出为(u64, u64)元组

带种子的哈希

use ch_cityhash102::city_hash_102_64_with_seed;

let hash = city_hash_102_64_with_seed(b"example data", 42);
println!("Seeded 64-bit hash: {}", hash);

性能优化建议

  1. 对于小字符串(<=16字节),直接使用64位哈希
  2. 对于中等长度字符串(17-240字节),使用128位哈希
  3. 对于大字符串(>240字节),考虑分块处理

示例:构建简单哈希表

use ch_cityhash102::city_hash_102_64;
use std::collections::HashMap;

fn main() {
    let mut map = HashMap::new();
    
    let key1 = "user1";
    let hash1 = city_hash_102_64(key1.as_bytes());
    map.insert(hash1, "John Doe");
    
    let key2 = "user2";
    let hash2 = city_hash_102_64(key2.as_bytes());
    map.insert(hash2, "Jane Smith");
    
    if let Some(name) = map.get(&hash1) {
        println!("Found user: {}", name);
    }
}

注意事项

  1. CityHash不是加密哈希,不适用于安全敏感场景
  2. 不同版本的CityHash可能产生不同的哈希值
  3. 在32位系统上性能可能不如64位系统

基准测试

可以通过cargo bench运行内置的基准测试来比较不同哈希函数的性能:

#[bench]
fn bench_cityhash_64(b: &mut Bencher) {
    let data = "benchmark string".repeat(100);
    b.iter(|| city_hash_102_64(data.as_bytes()));
}

完整示例代码

下面是一个综合使用ch_cityhash102库的完整示例:

// 导入所需的哈希函数
use ch_cityhash102::{city_hash_102_64, city_hash_102_128, city_hash_102_64_with_seed};
use std::collections::HashMap;

fn main() {
    // 示例1:基本64位哈希
    let small_data = "short string";
    let hash_64 = city_hash_102_64(small_data.as_bytes());
    println!("64-bit hash for '{}': {}", small_data, hash_64);
    
    // 示例2:128位哈希
    let medium_data = "this is a medium length string for testing";
    let hash_128 = city_hash_102_128(medium_data.as_bytes());
    println!("128-bit hash for '{}': {:?}", medium_data, hash_128);
    
    // 示例3:带种子的哈希
    let seed = 12345;
    let seeded_hash = city_hash_102_64_with_seed(b"data with seed", seed);
    println!("Seeded hash: {}", seeded_hash);
    
    // 示例4:构建哈希表
    let mut user_db = HashMap::new();
    
    // 添加用户记录
    let users = vec![
        ("alice", "Alice Johnson"),
        ("bob", "Bob Smith"),
        ("charlie", "Charlie Brown")
    ];
    
    for (username, fullname) in users {
        let hash = city_hash_102_64(username.as_bytes());
        user_db.insert(hash, fullname);
    }
    
    // 查询用户
    let query = "alice";
    let query_hash = city_hash_102_64(query.as_bytes());
    if let Some(name) = user_db.get(&query_hash) {
        println!("Found user {}: {}", query, name);
    } else {
        println!("User {} not found", query);
    }
    
    // 性能测试示例
    let large_data = "a".repeat(500); // 创建500字节的字符串
    let hash_large = city_hash_102_128(large_data.as_bytes());
    println!("Large data hash: {:?}", hash_large);
}

这个完整示例展示了:

  1. 对不同长度的字符串使用合适的哈希函数
  2. 使用带种子的哈希
  3. 实际应用中构建哈希表
  4. 处理大字符串的哈希计算

您可以根据实际需求调整代码,例如:

  • 对于非常大的数据,可以实现分块处理
  • 根据性能测试结果选择最适合的哈希位数
  • 在需要时使用不同的种子值
回到顶部