我一直在对可变和不可变列表进行一些性能检查。我创建了以下测试。测试非常简单,我想知道我应该考虑哪些方面来改进lambda表达式,使其性能与for循环最接近或更好。
现在使用,我列出了其中一些:
还有哪些方面会影响?
增强版 - 经过时间:141
For - Elapsed time:109
迭代器 - 经过的时间:125
流 - 经过的时间:172
并行流 - 经过时间:94
可选流 - 已用时间:156
可选并行流 - 已用时间:140
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
class MyObject {
private Integer id;
private String name;
private String message;
private MySecondObject object;
public MyObject(Integer id, String name, String message, MySecondObject object) {
this.id = id;
this.name = name;
this.message = message;
this.object = object;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public MySecondObject getObject() {
return object;
}
public void setObject(MySecondObject object) {
this.object = object;
}
@Override
public int hashCode() {
int hash = 8;
hash = 14 * hash + Objects.hashCode(this.id);
hash = 14 * hash + Objects.hashCode(this.name);
hash = 14 * hash + Objects.hashCode(this.message);
hash = 14 * hash + Objects.hashCode(this.object);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final MyObject other = (MyObject) obj;
if (!Objects.equals(this.name, other.name)) {
return false;
}
if (!Objects.equals(this.message, other.message)) {
return false;
}
if (!Objects.equals(this.id, other.id)) {
return false;
}
return Objects.equals(this.object, other.object);
}
@Override
public String toString() {
return "\nMyObject{" + "id=" + id + ", name=" + name + ", message=" + message + ", object=" + object + '}';
}
}
class MySecondObject {
private Integer id;
private String name;
private String message;
public MySecondObject(Integer id, String name, String message) {
this.id = id;
this.name = name;
this.message = message;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public int hashCode() {
int hash = 7;
hash = 13 * hash + Objects.hashCode(this.id);
hash = 13 * hash + Objects.hashCode(this.name);
hash = 13 * hash + Objects.hashCode(this.message);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final MySecondObject other = (MySecondObject) obj;
if (!Objects.equals(this.name, other.name)) {
return false;
}
if (!Objects.equals(this.message, other.message)) {
return false;
}
return Objects.equals(this.id, other.id);
}
@Override
public String toString() {
return "MySecondObject{" + "id=" + id + ", name=" + name + ", message=" + message + '}';
}
}
class MyObjectUtil {
private MyObjectUtil() {
}
public static List<?> getList() {
List<MyObject> myObjectList = new ArrayList<>();
final ThreadLocalRandom r = ThreadLocalRandom.current();
for (int i = 0; i < 1_000_000; i++) {
myObjectList.add(new MyObject(r.nextInt(), "Name " + i, "Message " + i, new MySecondObject(r.nextInt(), "Second Object " + i, "Message " + i)));
}
myObjectList.add(new MyObject(r.nextInt(), "Name " + 0, "Message " + 0, null));
myObjectList.sort((a, b) -> a.getId().equals(b.getId()) ? 0 : a.getId()> b.getId()? 1 : -1);
return Collections.unmodifiableList(myObjectList);
//return myObjectList;
}
}
public class MyObjectListTest {
public static void main(String[] args) {
List<MyObject> myObjectList = (List<MyObject>) MyObjectUtil.getList();
long begin = System.currentTimeMillis();
List<Integer> idList = new ArrayList<>();
if (myObjectList != null) {
for (MyObject object : myObjectList) {
if (object != null && object.getObject() != null) {
idList.add(object.getObject().getId());
}
}
}
long end = System.currentTimeMillis();
System.out.println("\nEnhanced For - Elapsed time: " + (end - begin));
idList = null;
begin = System.currentTimeMillis();
idList = new ArrayList<>();
if (myObjectList != null) {
for (int i = 0; i < myObjectList.size(); i++) {
MyObject o = myObjectList.get(i);
if (o != null && o.getObject() != null) {
idList.add(o.getObject().getId());
}
}
}
end = System.currentTimeMillis();
System.out.println("\nFor - Elapsed time: " + (end - begin));
idList = null;
begin = System.currentTimeMillis();
idList = new ArrayList<>();
if (myObjectList != null) {
for (Iterator<MyObject> it = myObjectList.iterator(); it.hasNext();) {
MyObject m = it.next();
if (m.getObject() != null) {
idList.add(m.getObject().getId());
}
}
}
end = System.currentTimeMillis();
System.out.println("\nIterator - Elapsed time: " + (end - begin));
idList = null;
begin = System.currentTimeMillis();
if (myObjectList != null) {
idList = myObjectList
.stream()
.map(MyObject::getObject)
.filter(Objects::nonNull)
.map(MySecondObject::getId)
.collect(Collectors.toList());
}
end = System.currentTimeMillis();
System.out.println("\nStream - Elapsed time: " + (end - begin));
idList = null;
begin = System.currentTimeMillis();
if (myObjectList != null) {
idList = myObjectList
.parallelStream()
.map(MyObject::getObject)
.filter(Objects::nonNull)
.map(MySecondObject::getId)
.collect(Collectors.toList());
}
end = System.currentTimeMillis();
System.out.println("\nParallel Stream - Elapsed time: " + (end - begin));
idList = null;
begin = System.currentTimeMillis();
idList = Optional.ofNullable(myObjectList)
.orElseGet(Collections::emptyList)
.stream()
.map(MyObject::getObject)
.filter(Objects::nonNull)
.map(MySecondObject::getId)
.collect(Collectors.toList());
end = System.currentTimeMillis();
System.out.println("\nOptional Stream - Elapsed time: " + (end - begin));
idList = null;
begin = System.currentTimeMillis();
idList = Optional.ofNullable(myObjectList)
.orElseGet(Collections::emptyList)
.parallelStream()
.map(MyObject::getObject)
.filter(Objects::nonNull)
.map(MySecondObject::getId)
.collect(Collectors.toList());
end = System.currentTimeMillis();
System.out.println("\nOptional Parallel Stream - Elapsed time: " + (end - begin));
}
}
感谢。