스와 작은 따뜻한 자바 성능 최적화

코드 최적화, 매우 중요한 문제. 어떤 사람들은 수정, 변경 및 그것의 코드의 효율성에 영향을 무엇을 변경하지 않는 것이없는 쓸모없는, 몇 가지 작은 장소를 느낄 수 있습니다? 문제는 내가 고래의 내부처럼, 그것은 새우 유용 먹고, 바다처럼 생각 무엇인가? 최대 공급 하였다 고래 쓸모없는, 그러나, 이후에 하나 개 이상의 새우 먹는다.

하지 BUG 프로젝트는 가능한 한 빨리 라인에 초점을 맞춘 경우 코드 최적화, 동일, 다음 시간은 코드의 세부 사항을 심의하지 수, 발생할 수 있지만 코드를 개발하고 유지하기 위해 충분한 시간이 있다면,이 시간 각을 고려할 필요가있다 당신은 세부 사항을 최적화하며, 절대적으로 업그레이드되는 코드의 효율성에 대한 축적 된 하나의 작은 최적화 점 하나 있습니다.

가속은 서둘러 낭비를하게 도달하기 위해 낭비하게!

코드 최적화의 목표는 :

  • 코드 크기 감소
  • 코드 실행의 효율성을 향상

코드 최적화 세부 사항

1, 최종 수정을 사용하려고

최종 수정 클래스가 자바 코어 API에서 파생되지 않고, 예를 java.lang.String의 전체 클래스는 최종 결과이며, 최종 응용 프로그램의 많은 예들이있다. 최종 수정자를 지정하는 클래스는 상속 될 수 없습니다 클래스의 최종 예선을 허용 지정하는 방법 방법을 만들기 위해 다시 할 수 없습니다. 클래스 결승전을 개발하는 경우, 모든 메소드의 클래스는 마지막이다. 자바 컴파일러는 모든 메소드, 자바의 운영 효율성 향상을위한 인라인 큰 역할과 최종 내에서 기회를 찾을 것입니다, 50 %의 평균 성능을 향상시킬 수 있습니다.

2 개체를 재사용하려고

특히 사용 String 객체에서 대신 문자열의 StringBuilder 나 StringBuffer와 연결이 사용되어야한다. Java 가상 머신이 객체를 생성하는 데 시간이 걸릴뿐만 아니라 이후, 미래는 또한 프로그램의 성능에 큰 영향을 가져올 것이다, 그러므로, 쓰레기 수거 및 처리에 대한 이러한 개체에 시간을 보내고 너무 많은 객체를 생성해야 할 수도 있습니다.

3, 로컬 변수를 사용하려고

스택에 저장된 통화 방법 파라미터를 호출 할 때 전달 임시 변수가 생성 빠르며 등 정적 변수, 인스턴스 변수와 같은 다른 변수는, 서서히, 힙에 생성된다. 또한, 조작의 방법으로 만들어진 적층 변수 콘텐츠가 없어, 추가적인 가비지 콜렉션이 완료되지 않는다.

도 4에서, 흐름 닫기

IO 스트림 작업이, 사용 후 즉시 해제 자원을 종료 할 때 자바 프로그래밍, 데이터베이스 연결,주의하십시오. 때문에 이러한 큰 개체의 오버 헤드가 발생 멋진 액션의, 사소한 실수는 심각한 결과로 이어질 것입니다.

도 5에서, 변수의 중복 계산을 최소화

명확한 개념, 메서드 호출은 방법은 단 하나의 문장 경우에도, 방법, 메서드를 호출 완료 복구 사이트를 호출 할 때 사이트를 보호하는 스택 프레임의 생성을 포함, 소비된다. 따라서, 예를 들어, 다음과 같은 작업 :

for(int i=0;i<list.size;i++){}

권장 대안 :

for(int i=0,int length=list.size;i<length;i++){}

이러한 방법으로는 list.size의 많은 시간, 그것은 소비를 많이 줄일 수 있습니다.

필요한 경우에만 생성 가능한 한 6, 게으른 로딩 전략,

예를 들면 :

String str = "aaa";if (i == 1){list.add(str);}

권장 대안 :

if (i == 1){String str = "aaa";list.add(str);}

7 이상주의

성능에 이상 해로운. 예외는, 새로운 객체를 생성 정보 수집 통화 추적의 스택을 검사 로컬 동기화 방법에 fillInStackTrace의 Throwable라는 인터페이스의 생성자,에 fillInStackTrace 메소드를 호출 먼저 발생된다. 새로운 객체가 프로세스에서 생성되기 때문에 언제 까지나 throw되는 예외가있는 한, Java 가상 머신은, 호출 스택을 조정해야합니다. 유일한 예외가 에러 처리를 위해 사용될 수 있고, 이는 프로그램의 흐름을 제어하는 ​​데 사용되어서는 안된다.

8. 루프 trycatch 사용하지 않는 것이 가장 외측에 배치해야

최후의 수단 않는 한. 그래서 당신의 수석 리더십만큼, 1시, 휴지통이 코드를 작성하는 이유는 대부분의 아마 꾸짖 것 강박 장애를 작성 아무 이유없이합니다.

도 9는 초기 길이를 지정 하부층가 어레이 구현 도구로서 설정 추가되는 내용의 길이를 추정하기 위해 시도 할 수있다

이러한의 StringBuilder 예 등의 ArrayList, LinkedLlist, StringBuilder에, StringBuffer를 HashMap에, HashSet에, 등 :

①의 StringBuilder // 기본 공간은 16 개 문자를 할당

②의 StringBuilder (INT 크기) // 기본 공간 할당 크기 문자

③ StringBuider (문자열 STR) // 16 자 + st.length 문자 공간의 기본 할당

초기 용량 설정, 성능이 크게 향상 될 수있다. 예를 들어, 모두 StringBuilder를 들어, 길이는 저장할 수있는 현재의 StringBuilder의 문자 수를 나타냅니다. StringBuilder의 최대 용량에 도달 할 때, 그 자체가 모두 StringBuilder는 최대 용량에 도달 할 때마다 2 플러스 2 배의 전류 용량을 증가하기 때문에, 새로운 문자 배열하고 기존의 캐릭터를 만들어야합니다 아주 시간이 많이 걸리는 작업 성능이다 - 문자 배열의 새 배열에 복사 된 내용. 당신은 길이 2 5000 4096의 가장 가까운 전력, 다음 이중으로 모든 확장 2를 지정하지 않고 5000 개 문자에 대한 저장소에 문자 배열을 추정 할 수있는 경우, 상상 :

시작은 문자 배열 5000의 크기를 지정할 수있는 경우 ① 다음 4096, 8194 및에 기초하여, 문자 배열의 크기를 적용됩니다에 해당까지 추가보다 두 배 공간보다 절약, 12,290 문자 배열의 크기를 제기 .

② 문자의 새로운 배열에 복사 한 4096 개 문자 이동합니다.

이러한 방법으로, 메모리 공간의 낭비 및 코드의 효율성을 줄일 수 있습니다. 합리적인 초기 용량을 설정하는 도구의 집합을 달성하기 위해 기본 배열이 잘못되지 않습니다에 따라서, 그것은 즉각적인 결과를 가져올 것이다. 단, 같은 세트의 배열 해시 맵 + 링크리스트의 구현으로 만 때문에 연결 테이블에서 객체의 가능성, 같은 크기의 초기 추정과 집합의 크기를 할 수는 거의 제로입니다. 이 사용될 수있다 새로운 해시 맵 (128), 새로운 해시 맵 (256)을 구비 2,000 요소가 있다고 예상되는 경우, (2)의 초기 크기를 N 번째의 파워를 설정하는 추천.

10 System.arraycopy에 명령을 사용하여, 대량의 데이터를 복사 할 때

곱셈과 나눗셈을 사용하는 11 시프트 연산

예를 들면 :

int a = 0;
int b = 0;
for (int i = 0; i < 1000000000; i++){
   a = i * 8;
   b = i / 2;
}

컴퓨터 하단에, 작동 위치이기 때문에 이동 작업은 크게 성능을 향상시킬 수 있습니다 다음과 같이 빠른, 그것은 개정 제안, 가장 편리한 :

int a1 = 0;
int b1 = 0;
for (int i = 0; i < 1000000000; i++){
    a1 = i << 3;
    b1 = i >> 1;
}

시프트 작업을 빠르게 할 수 있지만 코드가 덜 잘 적절한 주석을 추가하는 것이 가장 좋습니다, 이해 할 수 있습니다. 

만 더 2 밀리 초를 조금 까다 롭고, 얼마나 많은 사이클이 모든 느낌! ! !

도 12에서, 내부 루프는 객체 참조를 생성하지 않고 계속

예를 들면 :

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

이 연습은, 복사 개체 개체 참조 카운트를 메모리로 이어질 많은 셀 수, 그것은 메모리의 비용이, 읽을 것을 권장합니다 :

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

이 경우, 하나 개의 메모리 개체 개체 참조, 때마다 새로운 개체 개체 개체 개체 기준점 아무것도 다른,하지만 하나 개의 메모리, 따라서 크게 저장 메모리 공간까지.

단지 13 효율 타입 검사의 측면을 고려하여 배열을 최대한 표기 우리의 ArrayList를 사용하여 어레이의 크기를 결정할 수 없다

(14)를 사용 해시 맵을 만들기 위해, ArrayList를은 모두 StringBuilder는 스레드 보안 요구되지 아니하는 한,이 때문에 성능 오버 헤드로 이어지는 동기화 메커니즘의 사용에 사용하는 해시 테이블, 벡터, StringBuffer를, 후자의 3 권장하지 않습니다.

15, 배열에 대해 얘기하지 않는 공공 정적 최종 선언

도 16은, 적절한 경우에, 단일 모드의 실시 예를 활용할

부하의 부담을 줄일 부하에 시간을 줄이고 로딩의 효율성을 향상시킬 수있는 싱글 톤 패턴을 사용하여, 모든 장소는 간단한 용어, 싱글 톤 패턴은 주로 다음과 같은 세 가지 측면에 적용되는 단일 케이스 모델에 적합 :

스레드에 의한 자원 동기화 제어 동시 액세스를 자원의 사용을 제어 ①

자원을 절약하기 위해 ② 제어 인스턴스의 생성

직접 확립과 관련이없는 조건 ③ 제어 데이터를 공유하므로 여러 프로세스 또는 스레드에 관련되지 않은 통신의 사이 달성한다는

17, 정적 변수를 사용하여 피하려고

당신은 객체가 정적으로 정의 할 때, 알고, 다음 GC는 일반적으로 복구되지 않는이 힙 메모리는 객체에 의해 점령

public class A{
    private static B b = new B;
}

동일한 클래스 (A)의 라이프 사이클의 정적 변수 (B)에서, 클래스 A 제거되지 않으면, 프로그램이 종료 될 때까지 영구 메모리 오브젝트의 다음 레퍼런스 포인트 B.

18, 적시에 제거 세션이 더 이상 필요하지 않습니다

세션이 더 이상 활성 상태가 취소하지 않으려면 많은 서버는 기본 시간 제한 기간, 일반적으로 30 분해야합니다. 응용 프로그램 서버가 필요 더 많은 대화를 보존 할 때 메모리 부족 경우, 운영 체제가 디스크에 데이터의 일부를 전송합니다, 응용 프로그램 서버는 디스크에 비활성 세션을 덤프 수 있으며, 심지어 메모리 예외 밖으로 던져 할 수있다. 세션이 디스크에 덤프 할 경우, 먼저 직렬화되어야하며, 대규모 클러스터는, 객체 직렬화의 가격이 매우 높다. 세션이 더 이상 필요하지 않은 경우 따라서, 당신은 즉시 httpseesion 호출하지 세션의 무효화 방법을 지워야합니다.

19 인터페이스 세트는 대신 foreach 루프의 루프 가장 일반적인를 사용한다, 등의 ArrayList로 가능해, RandomAccess를 달성하기 위해

그들은 빠른 랜덤 액세스를 지원하는 것을 나타냅니다 가능해, RandomAccess 인터페이스를 달성,이 인터페이스의 주요 목적은 일반적인 알고리즘이 좋은 성능을 제공 할 때 임의 또는 순차 액세스 목록에 적용하기 위해 자신의 동작을 변경할 수 있도록하는 것입니다. 실제 경험 쇼 가능해, RandomAccess 인터페이스 클래스 인스턴스의 경우 차례의 통상의 사용 foreach 루프에 대한 높은 사이클 효율을 사용하여 랜덤 액세스, 순차 액세스하는 경우,보다 효율적인 반복자의 사용. 유사하게, 코드는 다음을 결정하기 위해 사용될 수있다 :

if (list instanceof RandomAccess){ 
    for (int i = 0; i < list.size; i++){}
}else{
    Iterator<?> iterator = list.iterable; while (iterator.hasNext){iterator.next}
}

기본이되는 구현의 foreach 문이 반복자입니다.

20 대신 동기 부호 블록을 사용하여 동기화 방법

(21)는 일정한 정적 마지막으로 선언하고 대문자라는

컴파일 중 함유량은 동작 중에 일정한 계산 된 값을 생성 피하기 위해, 상수 풀에 투입 될 수 있도록. 또한, 대문자 이름 상수 이름 쉽게 변수와 상수 사이를 구별 할 수있다.

(22)는, 일부 개체는 사용하지 않는 생성하지 않는 일부 클래스는 사용하지 않는 가져올 수 없습니다

23 일 프로그램은 반사를 사용하지 않는 실행

자바 반사는 비효율적 매우 강력한, 강력한 수단에 의해 제공됩니다. 실제로 필요가있는 경우하지 프로그램에 반사 특히 자주 사용이 메서드 Invoke 특히, 방법을 실행, 추천, 암시 접근 방식은 이러한 클래스는 프로젝트가 반사에 의해 시작시로드해야 반영됩니다 객체를 인스턴스화 메모리에 배치 - 프로젝트가 시작되는 시간에 관계없이 유일한 관심사 속도의 상호 작용을.

데이터베이스 연결 풀링 및 스레드 풀링을 사용하여 24,

빈번한 개구와 연결을 종료를 방지 할 수있는 전자, 후자 자주 생성 및 파괴를 방지 할 수 나사산

(25)는 버퍼의 입출력을 사용하여 IO 동작 스트림

입력 버퍼 및 출력 스트림 크게 IO 효율을 향상시킬 수있는, 즉의 BufferedReader, BufferedWriter로, BufferedInputStream을,의 BufferedOutputStream.

26, 삽입 순서는 장면의 ArrayList 더 랜덤 액세스하고, LinkedList의 소자를 이용하여 삭제 이상의 장면을 개재

27 대중 프로세스가 너무 많은 매개 변수가 있습니다 두지 마세요

28 문자열 변수와 문자열 상수는 시간 상수 문자열 사설 동일

널 포인터 예외를 방지하기 때문에 주로 마십시오.

29, 자바 알고있는 경우 (내가 == 1) 및하십시오 (1 == i)는이 차이는 없지만, 경우 이전의 존재와 말하기의 독서 습관,

30, 배열 toString 메소드를 사용하지 않는

도 31은, 기본 데이터를 필수 천이 범위를 벗어난 입력 내려하지 않는다

(32), 공통 데이터 컬렉션 클래스는 오프 제거 적시해야 사용되지 않습니다

모음 (재산 내부의 방법이 아니다이) 공개하면 그들에게 기준점은 항상 있기 때문에, 다음 요소의 세트 안에 자동으로 해제되지 않습니다. 데이터의 일부를 제거하는 것이 아니라 공공 수거 내부를 사용하지 않는 경우에 따라서, 시스템이 메모리 누수 문제가 그래서, 공공 수거가 증가하게됩니다.

33 문자열에 대한 기본 형식으로, toString 가장 빠른, "느린 한 String.valueOf, 데이터 +"를 따라

우리는 toString 메소드의 사용에 우선 순위를주고, 시간의 문자열로 기본 데이터 유형 후 발생 그래서. 그것은 단순한 이유에 관해서는 :

방법을 Integer.toString를 메서드 호출을 기본 ① 한 String.valueOf하지만 전에에게 판사를 호출하면 짧은 것

② 방법을 Integer.toString를하는 것은 말이되지 않으며, 직접 전화

③ 전 + ""StringBuilder의 하단이 접함으로써 제 APPEND 방법을 사용하여 구현 toString 메소드는 문자열을 사용하고

세 대비 아래로, 분명히 가장 빠른 ②, ① 다음, ③ 최저

이송지도에 가장 효율적인 방법을 사용하여 34,

추천 (35), 리소스를 닫 ()는 별도로 작동

평균, 예를 들어, 나는 코드의 이러한 조각을 가지고 :

try{
    XXX.close;
    YYY.close;
}catch (Exception e){
...
}

제안 된 변경 사항은 다음과 같습니다

try{ 
    XXX.close; 
}catch (Exception e) {
 ... 
}
try{ 
    YYY.close; 
}catch (Exception e) {
 ... 
}

몇 가지 문제가 있지만, 그는 자원 누수를 방지 할 수 있었다. 예외가 발생 XXX.close 경우, 코드를 수정하지 않을 경우 나, 생각, 다음, 캐서린의 블록을 입력, YYY.close가 실행되지,이 자원이 복구되지 않습니다 YYY는, 그래서 점유하고있다 더 하나 개의 코드보다, 그것은 원인 리소스 핸들 누수에 가능하다. 그러나 표현은 어떠한 경우에도 XXX와 YYY 가까이 나올 것입니다 위의 보장하며 변경 후.

게시 된 110 개 원래 기사 · 원 찬양 8 · 전망 6928

추천

출처blog.csdn.net/guorui_java/article/details/104107390