非常快速地搜索Java中的特定字符

时间:2013-02-20 02:28:12

标签: java performance search character

这似乎有点像一个愚蠢的问题......也许是这样。但是我有一个我经常使用的功能,并且想知道这是否是最快的工作方式。该功能被使用了很多次,以至于任何速度增加实际上都是显而易见的。它只是检查一个字符是否是一个核苷酸(即:如果一个字符是'A','T','C'或'G'。

private static boolean isValidNucleotide(char nucleotide) {
    nucleotide = Character.toUpperCase(nucleotide);
    if(nucleotide == 'A') return true; 
    if(nucleotide == 'T') return true;
    if(nucleotide == 'C') return true;
    if(nucleotide == 'G') return true;
    return false;
}

这是完成这项工作的最快方式吗?或者您认为值得实现某种索引/地图/其他东西(可能在函数外部执行比较并将此文本复制到代码中的几个位置)?在Java中,我真的不是这方面的专家。

4 个答案:

答案 0 :(得分:5)

最快(但内存效率最低仍然是255字节还不错!)就像这样:

/* this is static member of class */
static boolean map[] = new boolean[256];
static {
    for(int j = 0; j < map.length; j++)
        map[j] = false;
    /* map your required values true here */ 
    map['A'] = true;
    map['T'] = true;
    map['C'] = true;
    map['G'] = true;
    /* make small letter here too */
    map['a'] = true;
    map['t'] = true;
    map['c'] = true;
    map['g'] = true;
}

然后制作一个这样的函数:

private static boolean isValidNucleotide(char nucleotide) {
    /* complexity is just one access to array */
    return map[nucleotide];
}

正如@paxdiablo所说,在java中,char是2个字节而不是1个字节,但是你的字符在这个范围内。只需将return map[nucleotide];更改为return map[0x00ff & nucleotide];即可。

您还可以将地图的大小更改为65536以确保安全,并避免任何类型的错误。 boolean map = new boolean[65536]

答案 1 :(得分:3)

您可以尝试switch-case,它通常用作小型交换机的表查找:

switch(nucleotide) {
case 'A':
case 'T':
case 'C':
case 'G':
    return true;
}
return false;

请注意,如果JVM的JIT经常被调用,它可能会使基于if的代码非常快。

答案 2 :(得分:1)

摆脱Character.toUpperCase并检查大写和小案例,它会显着加快你的功能。

private static boolean isValidNucleotide(char nucleotide) {       
    if(nucleotide == 'A' || nucleotide == 'a') return true; 
    // Rest of your conditions

    return false;
}

我使用您的原始功能进行了一项小测试,平均80 ms执行10000000 times,但当我删除Character.toUpperCase()并明确检查两个案例时40 ms只是,这是一个重大改进。

修改

使用@Shivam建议的Map解决方案,Kalra平均仅使用11 ms

答案 3 :(得分:-1)

我没试过,但您可以尝试使用Regex

查看效果