코드 최적화 및 코드 성능 향상

1. 방법

1. 클래스와 메소드의 최종 수정자를 지정해 보세요.

클래스가 final로 지정되면 해당 클래스의 모든 메서드가 final이 됩니다. Java 컴파일러는 모든 최종 메소드를 인라인할 수 있는 기회를 찾습니다 . 인라인은 Java 실행 효율성을 향상시키는 데 중요한 역할을 합니다. 자세한 내용은 Java 런타임 최적화를 참조하세요. 이렇게 하면 성능이 평균 50% 향상될 수 있습니다.

2. 변수

1. 루프 내에서 객체 참조를 지속적으로 생성하지 마십시오.

예를 들어:

for (int i = 1; i <= count; i++){
    
    
	Object  obj = new Object;
}

이 접근 방식을 사용하면 메모리에 개체 개체 참조 개수가 존재하게 됩니다. 개수가 크면 메모리를 소비하게 됩니다. 다음과 같이 변경하는 것이 좋습니다.

Object obj = null;
for (int i = 0; i <= count; i++) {
    
    
	obj = new Object; 
}

이 경우 메모리에는 Object 객체 참조의 복사본이 하나만 있는데, 새로운 Object가 생성될 때마다 Object 객체 참조는 다른 Object를 가리키지만 메모리에는 복사본이 하나만 있어 메모리가 크게 절약됩니다. 공간.

2. 기본 유형을 문자열로 변환

기본 데이터 유형을 문자열로 변환하려면 기본 데이터 유형 .toString이 가장 빠른 방법이고, String.valueOf가 두 번째이며, data+""가 가장 느립니다.

3. 변수의 초기값을 덮어쓰는 경우에는 변수에 초기값을 할당할 필요가 없습니다.

반례:

List<UserDO> userList = new ArrayList<>();
if (isAll) {
    
    
    userList = userDAO.queryAll();
} else {
    
    
    userList = userDAO.queryActive();
}

정례:

List<UserDO> userList;
if (isAll) {
    
    
    userList = userDAO.queryAll();
} else {
    
    
    userList = userDAO.queryActive();
}

4. 기본 데이터 유형을 사용하고 불필요한 박싱, 언박싱 및 널 포인터 판단을 피하십시오.

반례:

public static double sum(Double value1, Double value2) {
    
    
    double double1 = Objects.isNull(value1) ? 0.0D : value1;
    double double2 = Objects.isNull(value2) ? 0.0D : value2;
    return double1 + double2;
}
double result = sum(1.0D, 2.0D);

정례:

public static double sum(double value1, double value2) {
    
    
    return value1 + value2;
}
double result = sum(1.0D, 2.0D);

3. 상수

1. 상수를 static final로 선언하고 이름을 대문자로 지정합니다.

이러한 방식으로 런타임 중에 상수 값을 계산하지 않도록 컴파일 중에 이러한 내용을 상수 풀에 넣을 수 있습니다. 또한 상수 이름을 대문자로 지정하면 상수와 변수를 쉽게 구별할 수 있습니다.

2. JSON 변환 객체의 사용은 금지됩니다.

기능에는 문제가 없지만 성능에는 문제가 있습니다.

4. 객체

1. 가능한 한 객체를 재사용하라

특히 String 객체를 사용하는 경우에는 String 연결이 발생할 때 StringBuilder/StringBuffer를 대신 사용해야 합니다. JVM(Java Virtual Machine)은 객체 생성에 시간을 소비할 뿐만 아니라 향후 이러한 객체를 가비지 수집하고 처리하는 데에도 시간을 소비해야 하므로 너무 많은 객체를 생성하면 프로그램 성능에 큰 영향을 미치게 됩니다.

5. 사이클

1. 루프에서 try…catch…를 사용하지 말고 가장 바깥쪽 레이어에 넣으세요.

꼭 그래야 하지 않는 한. 아무 이유 없이 이런 글을 쓰는 것은 무리입니다.

2. for, Enhanced for, Iterator 선택

참조 문서: 목록 순회: for, foreach 반복기 속도 비교
요약:iterator 性能更优

// 遍历Set
Set<String> set = new HashSet<>();
set.add("a");
set.add("a");
set.add("b");
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()){
    
    
    System.out.println(iterator.next());
}

// 遍历List
List<String> list = new ArrayList<>();
list.add("a");
list.add("a");
list.add("b");
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
    
    
    System.out.println(iterator.next());
}

// 遍历Map
Map<String, String> nameMap = new HashMap<>();
nameMap.put("student1", "lihua");
Set<Map.Entry<String, String>> entries = nameMap.entrySet();
Iterator<Map.Entry<String, String>> iterator = entries.iterator();
while(iterator.hasNext()){
    
    
	Map.Entry<String, String> entry = iterator.next();
	System.out.println(entry.getKey());
	System.out.println(entry.getValue());
}

6. 수집

1. 배열리스트(ArrayList)와 링크드리스트(LinkedList)

ArrayList는 순차 삽입과 랜덤 액세스가 많은 시나리오에 사용되고, LinkedList는 요소 삭제와 중간 삽입이 많은 시나리오에 사용됩니다.

2. 추가할 콘텐츠의 길이를 추정할 수 있으면 초기 길이를 지정해 보세요.

예를 들어 ArrayList, LinkedLlist, StringBuilder, StringBuffer, HashMap, HashSet 등은 StringBuilder를 예로 사용합니다.

(1) StringBuilder//기본적으로 16자의 공백을 할당합니다.

(2) StringBuilder(int size) // 기본적으로 size 문자만큼의 공간을 할당합니다.

(3) StringBuilder(String str) // 기본적으로 16자 + str.length 문자 공간이 할당됩니다.

(4) List의 기본 길이는 10입니다.

(5) 맵의 기본 길이는 16입니다.

최대 용량에 도달하자마자 새 문자 배열을 생성한 다음 이전 문자 배열의 내용을 새 문자 배열에 복사해야 합니다. 이는 성능이 매우 많이 소모되는 작업입니다.

7. 문자열

1. 분할 사용을 피하십시오

꼭 필요한 경우가 아니면 분할 사용을 피해야 합니다. 분할은 정규 표현식을 지원하므로 효율성이 상대적으로 낮습니다. 수십, 수백만 건의 빈번한 호출은 많은 리소스를 소비합니다. 정말로 분할을 자주 호출해야 하는 경우에는 Apache의 사용을 고려해 볼 수 있습니다. StringUtils.split(string,char) 자주 분할하면 결과를 캐시할 수 있습니다.

2. 기본 유형을 문자열로 변환

기본 데이터 유형을 문자열로 변환하려면 기본 데이터 유형 .toString이 가장 빠른 방법이고, String.valueOf가 두 번째이며, data+""가 가장 느립니다.

3. 문자열을 추가할 때 문자열에 문자가 하나만 있는 경우 " " 대신 ' '를 사용합니다.

예:

public class STR {
    
    
	public void method(String s) {
    
    
		String string = s + "d" // violation.
		string = "abc" + "d" // violation.
	}
}

// 更正: 将一个字符的字符串替换成' '
public class STR {
    
    
	public void method(String s) {
    
    
		String string = s + "d // violation.
		string = "abc" + 'd' // violation.
	}
}

8. 방법

1. 클래스 멤버 변수와 관련이 없는 메소드를 정적 메소드로 선언하십시오.

정적 메서드의 장점은 클래스 인스턴스를 생성하지 않고 직접 호출할 수 있다는 것입니다. 정적 메서드는 더 이상 객체에 속하지 않고 객체가 위치한 클래스에 속합니다. 클래스 이름을 통해서만 액세스하면 되며, 객체를 반복적으로 생성하기 위해 리소스를 소비할 필요가 없습니다. 클래스 내의 프라이빗 메서드라도 클래스 멤버 변수를 사용하지 않는 경우에는 정적 메서드로 선언해야 합니다.

반례:

public int getMonth(Date date) {
    
    
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    return calendar.get(Calendar.MONTH) + 1;
}

정례:

public static int getMonth(Date date) {
    
    
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    return calendar.get(Calendar.MONTH) + 1;
}

추천

출처blog.csdn.net/m0_46638350/article/details/132445880