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());
}
性能优化建议
- 对于短字符串(小于32字节),CityHash算法已经进行了优化
- 对于长字符串,算法会自动选择最优的分块处理方式
- 避免频繁创建临时字节数组,尽量直接使用已有的字节切片
注意事项
- 该实现与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);
性能优化建议
- 对于小字符串(<=16字节),直接使用64位哈希
- 对于中等长度字符串(17-240字节),使用128位哈希
- 对于大字符串(>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);
}
}
注意事项
- CityHash不是加密哈希,不适用于安全敏感场景
- 不同版本的CityHash可能产生不同的哈希值
- 在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);
}
这个完整示例展示了:
- 对不同长度的字符串使用合适的哈希函数
- 使用带种子的哈希
- 实际应用中构建哈希表
- 处理大字符串的哈希计算
您可以根据实际需求调整代码,例如:
- 对于非常大的数据,可以实现分块处理
- 根据性能测试结果选择最适合的哈希位数
- 在需要时使用不同的种子值