MurmurHash3

二、应用

广泛应用于各开源产品,Java 界中 Redis,Memcached,Cassandra,Hadoop,HBase,Lucene,spark,nginx,常见的大数据库底层,都使用了这个算法作为底层的存储算法。

介绍

MD5 生成的哈希值是 128 比特的。这里的哈希值指的是二进制的值,而不是 HEX 或 base64 格式化后的人类可读的值。通常我们提到的 32 位 MD5 是指由 32 个字符组成的,HEX 格式的 MD5。MurMurHash 算法家族的最新一员为MurMurHash3,支持32位和128位,推荐使用128位的MurMurHash3。是原作者被Google挖去之后基于Murmur2的缺陷做了改进。

32位的,在某些场景下,比如哈希的对象长度小于 128 位,或者存储空间要求占用小,或者需要把字符串转换成一个整数,这一特性就能帮上忙。当然,32 位哈希值发生碰撞的可能性就比 128 位的要高得多。当数据量达到十万时,就很有可能发生碰撞。

贴一个网上的简单 MurMurHash2、MurMurHash3、MD5 的 benchmark:

lua-resty-murmurhash3/README.md at master · spacewander/lua-resty-murmurhash3 · GitHub

这里的结论:MurMurHash3 128 位版本的速度是 MD5 的十倍。有趣的是,MurMurHash3 生成 32 位哈希的用时比生成 128 位哈希的用时要长。原因在于MurMurHash3_128 针对现代 x64 平台cpu进行了优化。

Murmur是一个良好的通用散列函数系列,适用于非加密用法。MurmurHash提供以下好处:

简单(根据生成的汇编指令数量)。

良好的分布(几乎所有键组和铲斗尺寸均通过卡方检验。

好 雪崩 行为(最大偏差0.5%)。

良好的碰撞阻力(通过Bob Jenkin的frog.c酷刑测试。对于4字节键没有碰撞,没有小的(1到7位)差异)。

在Intel/AMD硬件上表现出色,散列质量和CPU消耗之间的良好折衷。

三、MurmurHash使用

1.导包

Java版:google guava 包中提供了使用工具类:

<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1.1-jre</version>

2.使用

import java.nio.charset.StandardCharsets;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
 
public class MurmurHashTest {
 
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            String hexHashString = getHexHashString("qwerqwerqwer");
            System.out.println(hexHashString);
        }
    }
 
    public static String getHexHashString(String str) {
        HashFunction hashFunction = Hashing.murmur3_128();
        return hashFunction.hashString(str, StandardCharsets.UTF_8).toString();
    }
}

四、性能测试

public class MurmurHashTest {
 
    public static void main(String[] args) {
        long l = System.nanoTime();
        for (int i = 0; i < 10000 * 10000; i++) {
            String hexHashString = getHexHashString("yzh123456qwer杨子");
            // System.out.println(hexHashString);
        }
        long time = System.nanoTime() - l;
        System.out.println("一亿数据,一共花费时间:" + time / (1000 * 1000 * 1000) + "秒");
 
        long ns = time / (10000 * 10000);
        System.out.println("一亿数据,每条数据花费时间:" + ns + "纳秒");
    }
 
    public static String getHexHashString(String str) {
        HashFunction hashFunction = Hashing.murmur3_128();
        return hashFunction.hashString(str, StandardCharsets.UTF_8).toString();
    }
}

结果:

一亿数据,一共花费时间:20秒
一亿数据,每条数据花费时间:200纳秒

MD5的性能测试:

一亿数据,一共花费时间:32秒 一亿数据,每条数据花费时间:323纳秒

相关推荐

  1. MurmurHash3

    2024-03-30 01:36:05       46 阅读
  2. C语言实现MurmurHash1算法

    2024-03-30 01:36:05       37 阅读
  3. 3.11笔记3

    2024-03-30 01:36:05       39 阅读
  4. 3.3 语法规则

    2024-03-30 01:36:05       46 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-30 01:36:05       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-30 01:36:05       106 阅读
  3. 在Django里面运行非项目文件

    2024-03-30 01:36:05       87 阅读
  4. Python语言-面向对象

    2024-03-30 01:36:05       96 阅读

热门阅读

  1. Spring和SpringBoot的区别

    2024-03-30 01:36:05       49 阅读
  2. 11、Spring CLI中Action指南

    2024-03-30 01:36:05       42 阅读
  3. yarn的安装和使用

    2024-03-30 01:36:05       48 阅读
  4. js中遍历数组,map方法和reduce方法有什么区别?

    2024-03-30 01:36:05       39 阅读
  5. 为什么编码器-解码器结构能够保存空间信息

    2024-03-30 01:36:05       40 阅读
  6. <个人笔记>位运算

    2024-03-30 01:36:05       39 阅读