从具有 20,000 条记录的网格中快速查找重复记录,而无需快速访问数据库
Find duplicate records from a grid that has 20,000 records without any access to DB fastly
在我的测试自动化中,我无法访问 XML 或 database.I 想要查找网格中特定列的重复记录。我的网格有 20,000 records.The 唯一的问题是我们无法访问任何数据库,因此如果我更改页面,它会很慢,每个页面加载 50 records.There 是 20,000 条记录的性能问题。
创建一个 HashMap<Integer, ArrayList<YourObject>>
- 每次你通过对象 Id 获得相同的对象时将其放入地图中并将其添加到 ArrayList
生成此结果后,您可以缓存它,这样就不必在每次访问页面时重新生成它。然而在 2 毫秒,你可能不会打扰。
这是一个计时的例子
static class MyRecord {
String text;
int id;
double d;
public MyRecord(String text, int id, double d) {
this.text = text;
this.id = id;
this.d = d;
}
public int getId() {
return id;
}
}
public static void main(String[] args) {
for (int t = 0; t < 100; t++) {
long start = System.nanoTime();
Random rand = new Random();
Map<Integer, MyRecord> map = IntStream.range(0, 20000)
.mapToObj(i -> new MyRecord("text-" + i, rand.nextInt(i+1), i))
.collect(Collectors.groupingBy(MyRecord::getId,
Collectors.reducing(null, (a, b) -> a == null ? b : a)));
long time = System.nanoTime() - start;
System.out.printf("Took %.1f ms to generate and collect duplicates%n", time/1e6);
}
}
此测试需要 2.0 毫秒来生成和整理重复记录。您可以在 Java 7 中编写相同的代码,只是写的时间更长,但不会更慢。如果它不必生成记录,它会更快。
为了比较,我让它与
并发
Map<Integer, MyRecord> map = IntStream.range(0, 20000).parallel()
.mapToObj(i -> new MyRecord("text-" + i, rand.nextInt(i+1), i))
.collect(Collectors.groupingByConcurrent(MyRecord::getId,
Collectors.reducing(null, (a, b) -> a == null ? b : a)));
但现在需要 16 毫秒。 :P
这是一个基本选项。出于演示目的,我创建了一个包含 20,000 多条记录的列表,然后检查其中的重复项 - 耗时 29 毫秒。
基本上,我们的想法是扫描您的值,并针对每个值验证它是否是唯一的 - 如果是,则将其放入您比较的 "unique" 桶中;否则 - 将其放入重复项桶中。
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class FindDuplicates {
/**
* @param args
*/
public static void main(String[] args) {
List<String> values = new ArrayList<String>();
Set<String> unique = new HashSet<String>();
Set<String> duplicates = new HashSet<String>();
values.add("1");
values.add("2");
values.add("3");
for(int i=0;i<=20000;i++)
{
values.add(Integer.toString(i));
}
values.add("1");
values.add("2");
values.add("4");
long before = System.currentTimeMillis();
for(String str : values)
{
if(unique.contains(str))
{
duplicates.add(str);
}
else
{
unique.add(str);
}
}
long after = System.currentTimeMillis();
System.out.println("Processing time: " + (after-before));
System.out.println("total values: " + values.size());
System.out.println("total unique: " + unique.size());
System.out.println("total duplicates: " + duplicates.size());
}
}
在我的测试自动化中,我无法访问 XML 或 database.I 想要查找网格中特定列的重复记录。我的网格有 20,000 records.The 唯一的问题是我们无法访问任何数据库,因此如果我更改页面,它会很慢,每个页面加载 50 records.There 是 20,000 条记录的性能问题。
创建一个 HashMap<Integer, ArrayList<YourObject>>
- 每次你通过对象 Id 获得相同的对象时将其放入地图中并将其添加到 ArrayList
生成此结果后,您可以缓存它,这样就不必在每次访问页面时重新生成它。然而在 2 毫秒,你可能不会打扰。
这是一个计时的例子
static class MyRecord {
String text;
int id;
double d;
public MyRecord(String text, int id, double d) {
this.text = text;
this.id = id;
this.d = d;
}
public int getId() {
return id;
}
}
public static void main(String[] args) {
for (int t = 0; t < 100; t++) {
long start = System.nanoTime();
Random rand = new Random();
Map<Integer, MyRecord> map = IntStream.range(0, 20000)
.mapToObj(i -> new MyRecord("text-" + i, rand.nextInt(i+1), i))
.collect(Collectors.groupingBy(MyRecord::getId,
Collectors.reducing(null, (a, b) -> a == null ? b : a)));
long time = System.nanoTime() - start;
System.out.printf("Took %.1f ms to generate and collect duplicates%n", time/1e6);
}
}
此测试需要 2.0 毫秒来生成和整理重复记录。您可以在 Java 7 中编写相同的代码,只是写的时间更长,但不会更慢。如果它不必生成记录,它会更快。
为了比较,我让它与
并发Map<Integer, MyRecord> map = IntStream.range(0, 20000).parallel()
.mapToObj(i -> new MyRecord("text-" + i, rand.nextInt(i+1), i))
.collect(Collectors.groupingByConcurrent(MyRecord::getId,
Collectors.reducing(null, (a, b) -> a == null ? b : a)));
但现在需要 16 毫秒。 :P
这是一个基本选项。出于演示目的,我创建了一个包含 20,000 多条记录的列表,然后检查其中的重复项 - 耗时 29 毫秒。
基本上,我们的想法是扫描您的值,并针对每个值验证它是否是唯一的 - 如果是,则将其放入您比较的 "unique" 桶中;否则 - 将其放入重复项桶中。
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class FindDuplicates {
/**
* @param args
*/
public static void main(String[] args) {
List<String> values = new ArrayList<String>();
Set<String> unique = new HashSet<String>();
Set<String> duplicates = new HashSet<String>();
values.add("1");
values.add("2");
values.add("3");
for(int i=0;i<=20000;i++)
{
values.add(Integer.toString(i));
}
values.add("1");
values.add("2");
values.add("4");
long before = System.currentTimeMillis();
for(String str : values)
{
if(unique.contains(str))
{
duplicates.add(str);
}
else
{
unique.add(str);
}
}
long after = System.currentTimeMillis();
System.out.println("Processing time: " + (after-before));
System.out.println("total values: " + values.size());
System.out.println("total unique: " + unique.size());
System.out.println("total duplicates: " + duplicates.size());
}
}