2014-08-28 9 views
5

내 용도는 애플리케이션 코드를 최적화하는 것입니다. 내 코드는 다음과 같습니다메서드가 비효율적 인 새로운 Integer (int) 생성자를 호출합니다. 대신 Integer.valueOf (int)를 사용하십시오.

내가 넷빈즈에 Findbugs에 의해 정적 분석했다
int a = 10; 
Map<String , Integer> myMap = new TreeMap<>(); 

myMap.put("first" , new Integer(a)); //[FindBugs] Method com.abc.xyz.Test.main(String[]) invokes inefficient new Integer(int) constructor; use Integer.valueOf(int) instead 

, 그것은 방법 "와 같은 경고/버그가 비효율적 새로운 정수 (INT) 생성자가 호출합니다 것을 보여준다 (Integer.valueOf를 사용 int) 대신 ".

나는 새로운 정수 (int)를 Integer.valueOf (int)를의 차이를 알고있다.

하나는 추가 개체를 만들고 다른 개체는 생성하지 않습니다. 또한 하나는 캐싱하지 않으며 다른 하나는 캐싱하지 않습니다.

그래서 나는 또한 (안 findbugs에 의해 에디터로) "정수에 불필요한 권투를"경고를 제공하는 ... 다시 다음과 같이

m.put("first" , Integer.valueOf(a)); // Unnecessary boxing to Integer 

하지만 내 코드를 수정했습니다.

그래서, 난 ....이 등 다시 마지막으로 모든 경고를 제공하지

m.put("first" , a); //No warning at all... 

그것을 변경되었습니다.

내 질문 :

1)이 link 제안 내부적으로 (("첫 번째"m.put) 컴파일러에 의해, A);에서 변환 중입니다. m.put ("first", Integer.valueOf (a));

(이 예제에는 List-ArrayList가 있으며 여기에는 Map-TreeMap ... FYI가 있습니다). 그러면 편집기에서 경고를 표시하는 이유는 무엇입니까? 그리고 어떻게해야합니까? 최적화 된 방법은 무엇입니까?

2) 만일 대신 맵의 다음 해시 같은 데이터 구조가 있다면 ???

3) 왜 편집기가 제공합니까 정수에 불필요한 권투는입니다.

4.) 왜 m.put ("first", a)이 작동합니까? 나는 프리미티브 변수을 전달하고지도의 put()은 객체 만 허용합니다. 그래서 자동 권투 때문에 그것입니까?

+1

예는 자동 권투로 인해의 1을 참조하십시오. –

+0

OK.thanks ... 그럼 최적화를위한 좋은 방법은 무엇입니까? 마지막 하나 ?? –

+0

나는 당신이 그것을 최적화 할 수 있다고 생각지 않는다, 자동 권투는 당신을 위해 똑같은 일을한다. 그래서 당신은 명시 적으로'valueOf (a)'를 할 필요가 없다. –

답변

4

1)이 링크는 내부적으로 (컴파일러 별) m.put ("first", a); m.put ("first", Integer.valueOf (a))에서 변환 중입니다.

(이 예제에는 List-ArrayList가 있으며 여기에는 Map-TreeMap ... FYI가 있습니다). 왜 편집인이 경고를 주는가? 그리고 어떻게해야합니까? 최적화 된 방법은 무엇입니까?

예, 컴파일러는 m.put("first", a)이 개체 만 허용하므로 자동 저장을 적용한다는 것을 알고 있습니다. 성능 측면에서 오토 보폭을 사용하거나 Integer.valueOf(a)을 쓰는 것은 아무런 효과가 없습니다.

반면에 new Integer(a)은 실제로는 Integer.valueOf(a)보다 느리지 않습니다. 차이점은 작은 절대 값 (기본값은 -128에서 127)입니다. Integer.valueOf(a)은 캐시를 사용합니다. 즉, 항상 새 개체를 만들지 않습니다. 다른 모든 값은 어쨌든 new Integer(a)을 호출합니다.

예 :

Integer.valueOf(1) == Integer.valueOf(1)이 얻을 것입니다 진정한
Integer.valueOf(1000) == Integer.valueOf(1000) 캐시가 여기

2. 이용되지 않는 경우 대신지도
new Integer(1) == new Integer(1)이) 거짓 얻을 것입니다 거짓 얻을 것입니다, 만약 거기에 HashTable 같은 데이터 구조가 무엇입니까 ???

왜 그런 질문을하십니까? HashTable이 있지만 동기 화되었으므로 HashMap보다 많은 오버 헤드가 발생하므로 정렬이 필요하면 동기화가 HashMap 또는 TreeMap이되어야합니다.

3) 3. 왜 편집기가 Integer에 불필요한 복싱을 제공합니까?

가독성 (aInteger.valueOf(a)보다 짧음) 때문일 수 있습니다.

4. 왜 m.put ("first", a)가 작동합니까? 왜냐하면 나는 기본 변수와지도의 put()을 전달하기 때문에 Object 만 받아 들인다. 자동 권투 때문입니까?

+0

고마워요 토마스 ... 당신이 내 의심을 분명히했습니다. 나는 똑같이 생각했지만 양쪽 모두 동일하거나 그렇지 않다는 것을 확신하지 못했다 ... 예, 독서 중에 -128에서 127 캐싱 범위에 대해 알게되었다 ... 평등을위한 +1 ... –

+0

그래서 우리는 맹목적으로 할 수 없다. 최적화. (Integer.valueOf (int)로 변경하면 일부 참조 비교 또는 equals()가 그림과 함께 나오는 경우 문제가 발생할 수 있음) ??? –

+1

@MananShah 예, 맹목적으로 최적화하는 것은 결코 좋은 생각이 아닙니다. :)'equals()'는 항상 동일한 결과를 가져와야하기 때문에 문제가되어야하지만, 객체 평등 (즉, ==)이 문제가 될 수 있습니다. 일반적으로 ==를 사용하는 것은주의 깊게 사용해야하며 _ 필요한 경우에만 사용해야합니다. – Thomas

1

4. 왜 m.put ("first", a)가 작동합니까? 왜냐하면 나는 기본 변수와지도의 put()을 전달하기 때문에 Object 만 받아 들인다.

오토 박싱.

INT는 자동으로 에디터가 정수에 불필요한 권투를 제공하는 이유

3) (이 경우 가능한 NullPointerException이와) 정수 및 그 반대로 변환됩니다.

이 코드를 작성할 필요가 없기 때문에. 컴파일러가 대신 해줄 것입니다.

그것은 보통 더 읽을 대신 맵의 해시와 같은 데이터 구조가 있다면, 다음의 경우가 동일하면

2) ??

예, JDK 수집은 Objects에서만 작동합니다. 기본 유형은 박스 처리되어야 함을 의미합니다. 런타임 비용이 적고 메모리 오버 헤드가 큽니다. Integer는 int보다 300 % 더 많은 메모리를 사용합니다.

당신은 그것을 벗어날 수 없습니다. 복싱 오버 헤드를 피할 수있는 유일한 방법은 기본 유형별로 하나의 클래스를 제공하는 GNU trove와 같은 전문 컬렉션을 사용하는 것입니다. 수백만 개의 기본 요소를 컬렉션에 저장하려는 경우에만 유용합니다.

마지막으로 새로운 정수 (x)를 쓰지 마십시오. Integer.valueOf (x)는 동일한 작업을 수행하지만 일반적으로 사용되는 일부 값에 대한 새 인스턴스를 만들지 않도록 내부 캐시를 유지합니다.

+0

NullPointerException 및 코드 가독성을 기억해 주셔서 감사합니다. 나는 GNU trove에 대해서 모른다. 물론 나는 그것을 읽을 것이다 ... 또한 정수에 관해서는 잘 모르겠다 = 메모리의 관점에서 int의 300 % ... :) nice. 다시 한 번 감사드립니다. –

+0

질문 1 때문에 토마스의 답변을 수락했습니다. 죄송합니다. 답변 하나만 수락 할 수 있습니다. –