2008-10-27 6 views

답변

23

매 복싱 발생에 대한 새로운 래퍼를 만드는 것이 매우 비쌉니다. 특히 일반적으로 메서드의 단일 범위에서 사용되는 것을 고려하면 Autoboxing은 공용 래퍼 풀을 사용합니다.

실제로 이것은 flyweight design pattern의 구현입니다. 잘 알려진 값에 대한 복싱이 발생하면 새 래퍼 인스턴스를 만드는 대신 미리 만들어진 인스턴스가 풀에서 페치되고 반환됩니다.

결과는 다음과 같습니다. 과학적 계산을 위해 자동 폭탄을 사용하지 않는 것이 좋습니다. 예를 들어, 코드 d = a * b + c는 a, b, c 및 d에 대해 정수 클래스를 사용하며 생성 된 코드는 d.valueOf (a.intValue() * b.intValue() + c.intValue)). 이러한 모든 메소드 호출에는 고유 한 오버 헤드가 있으므로 콜렉션에 프리미티브를 저장해야하는 경우 자동 보 통을 사용하는 것이 일반적입니다. 당신이 정수 포장 INT의 거 대 한 컬렉션이있는 경우

는 그리고 그렇다하더라도, 오버 헤드는 할 수는 reported in this article로, 이상 20 배까지 더 이상 실행 시간을 의미한다.


는 JB이 중요한 코멘트를 추가

또한 Wrapper.valueOf (원시) 래퍼의 풀을 사용합니다. 따라서 Integer.valueOf (5)를 new Integer (5)로 변경하십시오.

+0

과학적 계산을 위해 자동 폭탄을 사용하는 것은 여전히 ​​권장되지 않습니까? 예, 성능 문제 만있는 것입니까, 그렇지 않습니까? – grep

+1

@grep 확실하지 않음 : 나는 6 년 전 이상을 썼다. – VonC

5

예, 프리미티브는 객체보다 빠릅니다. java 5부터는 수동으로 하나를 다른 것으로 변환하지 않고도 프리미티브와 오브젝트를 혼합 할 수 있습니다. autoboxing 메커니즘이이를 처리합니다.

이것은 컬렉션에 프리미티브를 넣으면 컴파일러가 불평하지 않고 원시 객체를 암시 적으로 객체로 변환한다는 것을 의미합니다.

+0

어떤 경우에 더 빠릅니까? 전달 참조는 주변을 돌아 다니는 것만큼이나 빠릅니다. 예를 들어, –

+1

은 int를 취합니다. 정수는 단일 int 필드가 들어있는 Object입니다. Integer는 int보다 훨씬 부피가 크다. 이것은 int를 포함하는 Fedex 상자와 같습니다. – nkr1pt

10

을 사용하면이 사용되는 경우 프리미티브가 더 빠릅니다. 사용하기 전에 개체를 언 박싱해야하기 때문에. 따라서 VM이 수행 할 수있는 추가 단계가 있습니다. 예를 들어, Integer에 산술 연산을 수행하려면 먼저 산술을 수행하기 전에 int로 변환해야합니다.

많은 비즈니스 응용 프로그램에서 이것은 거의 문제가되지 않습니다. 그러나 그래픽 변환 프로세서와 같이 무언가를 매우 무겁게 쓰는 경우 신경을 쓰는 경향이 훨씬 큽니다.

1

응용 프로그램의 프로필을 작성하고 autoboxing이 성능이나 메모리 문제인지 확인하는 경우에만 래퍼를 통해 프리미티브를 사용하는 것에 대해 걱정해야한다고 말합니다. 내 경험에 비추어 볼 때, 원시 객체와 래핑 객체에 대해 말할 때 CPU주기 전에 메모리가 문제가된다.

+1

나는 동의하지 않는다. 처음에 효율적인 코드를 작성할 때 성능이 문제가되는 것을 기다리는 이유는 무엇입니까? 10 번 중 9 번은 래퍼 클래스가 제공하는 추가 기능이 필요하지 않으므로 왜 사용하나요? – alexmcchessers

+2

10 번 중 9 번은 최적화 할 필요가 없습니다. 대부분의 경우 오토 스프링스 기능의 이점을 얻을 수 있습니다. 그렇지 않은 경우 왜 지구에 추가 했습니까? 당신이 결코주의하지 않을 때 당신의 생활을 단단하게하는 아무 이유도 없다. – carson

+0

가끔씩 만 필요한 Java 언어의 많은 기능이 있습니다. 유용하지 않거나 추가되어서는 안된다고 말하는 것은 아닙니다. Autoboxing은 특정 상황에서 유용한 기능이지만, 래퍼를 사용하기 위해 래퍼를 사용하지 않아도된다고 생각합니다. – alexmcchessers

1

컬렉션에 저장소 프리미티브가 필요한 경우 commons-primitives을 사용할 수 있습니다.

필자는 래퍼에 프리미티브를 사용하는 것을 선호합니다. 래퍼가 반드시 있어야하는 곳만이 엔티티 클래스입니다. 데이터베이스는 null을 지원하므로 엔터티도 있어야합니다.

내가 한 번 데이터베이스 액세스의 기본 요소를 사용하여 프로젝트 (및 사제 ORM)에 근무 :

class Foo{ 
    int xxx = -1; 
... 
} 

을 그리고 당신은 있었다 :

void persist(Foo foo){ 
    ... 
    statement.setInt(15,foo.getXXX()==-1?null:foo.getXXX()); 
    ... 
} 

하나님이 악이었다.

관련 문제