高级Java优化

Sam*_*med 5 java language-agnostic algorithm distributed bigdata

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

我的问题更多的是基于高级别的设计优化.我们假设我必须做以下事情:

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

当字符串是几个句子时,这不是一个主要问题,但如果相反,我们想要计算900,000个单词文件中每个单词的出现.建设循环只是浪费时间.

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

我想我的主要观点是我倾向于使用循环来解决许多问题,并且我想摆脱使用循环的习惯.

提前致谢

山姆

ps如果可能,你可以产生一些伪代码来解决900,000字的文件问题,我倾向于理解代码比我能理解英语更好,我认为对于这个网站的大多数访问者来说都是一样的

Ray*_*oal 10

字计数问题是在大数据世界上最广泛覆盖的问题之一; 它就像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
}
Run Code Online (Sandbox Code Playgroud)

现在,一旦你的数据集太大而无法构建内存中的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
Run Code Online (Sandbox Code Playgroud)

这三个步骤在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());
        }
    } 
}
Run Code Online (Sandbox Code Playgroud)

现在这里是一个使用它的例子:

echo -e "Hey Moe! Woo\nwoo woo nyuk-nyuk why soitenly. Hey." | java WordGenerator
Run Code Online (Sandbox Code Playgroud)

这输出

hey
moe!
woo
woo
woo
nyuk-nyuk
why
soitenly.
hey.
Run Code Online (Sandbox Code Playgroud)

您可以将此标记生成器与sort和uniq结合使用,如下所示:

echo -e "Hey Moe! Woo\nwoo woo nyuk-nyuk why soitenly. Hey." | java WordGenerator | sort | uniq
Run Code Online (Sandbox Code Playgroud)

生产

hey
hey.
moe!
nyuk-nyuk
soitenly.
why
woo
Run Code Online (Sandbox Code Playgroud)

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

Scanner input = new Scanner(System.in).useDelimiter(Pattern.compile("\\P{L}"));
Run Code Online (Sandbox Code Playgroud)

现在

echo -e "Hey Moe! Woo\nwoo woo^nyuk-nyuk why#2soitenly. Hey." | java WordGenerator | sort | uniq
Run Code Online (Sandbox Code Playgroud)

产量

hey
moe
nyuk
soitenly
why
woo
Run Code Online (Sandbox Code Playgroud)

输出中有一个空行; 我会告诉你如何打击它.:)