java - 高级 Java 优化

标签 java algorithm language-agnostic distributed bigdata

关于如何使用 for、while 和 do-while 循环进行低级 Java 优化,以及是否有必要,有很多问题、答案和意见。

我的问题更多是基于高级设计的优化。假设我必须执行以下操作:

对于给定的字符串输入,计算字符串中每个字母的出现次数。

当字符串是几个句子时,这不是一个大问题,但是如果我们想统计一个 900,000 词文件中每个词的出现次数怎么办。构建循环只会浪费时间。

那么什么是可以应用于此类问题的高级设计模式。

我想我的主要观点是我倾向于使用循环来解决很多问题,我想改掉使用循环的习惯。

提前致谢

山姆

附注如果可能的话,你能生成一些伪代码来解决 900,000 字的文件问题,我对代码的理解往往比我对英语的理解要好,我认为对于这个网站的大多数访问者来说都是一样的

最佳答案

字数统计问题是大数据领域中涉及最广泛的问题之一;它有点像 Hadoop 等框架的 Hello World。您可以在整个网络上找到有关此问题的大量信息。

无论如何,我会给你一些想法。

首先,900000 个单词可能仍然小到可以为其构建 HashMap ,所以不要忽视明显的内存中方法。你说伪代码很好,所以:

h = new HashMap<String, Integer>();
for each word w picked up while tokenizing the file {
  h[w] = w in h ? h[w]++ : 1
}

现在,一旦您的数据集太大而无法构建内存中的 HashMap ,您可以像这样进行计数:

Tokenize into words writing each word to a single line in a file
Use the Unix sort command to produce the next file
Count as you traverse the sorted file

这三个步骤在 Unix 管道中进行。让操作系统在这里为您完成工作。

现在,随着您获得更多数据,您希望引入 hadoop 等 map-reduce 框架来对机器集群进行字数统计。

现在,我听说当你进入非常大的数据集时,在分布式环境中做事就不再有帮助了,因为传输时间超过了计数时间,而且在你的字数统计的情况下,一切都必须“是无论如何都要放回去”,所以你必须使用一些非常复杂的技术,我怀疑你可以在研究论文中找到这些技术。

附录

OP 要求提供一个用 Java 标记化输入的示例。这是最简单的方法:

import java.util.Scanner;
public class WordGenerator {
    /**
     * Tokenizes standard input into words, writing each word to standard output,
     * on per line.  Because it reads from standard input and writes to standard
     * output, it can easily be used in a pipeline combined with sort, uniq, and
     * any other such application.
     */
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            System.out.println(input.next().toLowerCase());
        }
    } 
}

下面是一个使用它的例子:

echo -e "Hey Moe! Woo\nwoo woo nyuk-nyuk why soitenly. Hey." | java WordGenerator

这输出

hey
moe!
woo
woo
woo
nyuk-nyuk
why
soitenly.
hey.

您可以像这样将这个分词器与 sort 和 uniq 结合起来:

echo -e "Hey Moe! Woo\nwoo woo nyuk-nyuk why soitenly. Hey." | java WordGenerator | sort | uniq

屈服

hey
hey.
moe!
nyuk-nyuk
soitenly.
why
woo

现在,如果您只想保留字母并丢弃所有标点符号、数字和其他字符,请将您的扫描仪定义行更改为:

Scanner input = new Scanner(System.in).useDelimiter(Pattern.compile("\\P{L}"));

现在

echo -e "Hey Moe! Woo\nwoo woo^nyuk-nyuk why#2soitenly. Hey." | java WordGenerator | sort | uniq

产量

hey
moe
nyuk
soitenly
why
woo

输出中有一个空行;我会让你弄清楚如何打击它。 :)

关于java - 高级 Java 优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7048564/

相关文章:

sql - Hive 查询效率

algorithm - 谁能指出我的内容相关性算法吗?

python - 循环遍历一组 Python 数字或一组字母是否更快?

language-agnostic - 如何从一个方法返回两个值?

java - 查找所有包含关键字的子字符串

java - 将 24 小时制时间转换为 Joda-Time 中的上午/下午

Java8 流无法解析变量

language-agnostic - van Emde Boas树的应用?

algorithm - Dijkstra 图,最短路径

Java - 用一个字节索引到数组