3

작동중인 메커니즘이 100 % 확실하지 않으므로 추가 설명을 위해 여기에 게시하기로 결정했습니다.Java Array Efficiency

Java (Java가 있어야 함)로 많은 양의 데이터를 처리해야하는 프로젝트를 수행하고 있습니다. 가능한 한 효율적 이길 바랍니다. 효율적으로 말하면 메모리 및 속도 계산이 먼저 이루어져야하며 가독성이 두 번째가되어야 함을 의미합니다.

지금 내 데이터를 저장하는 두 가지 방법이있다 : MyObject

1) MyObject[][] V = new MyObject[m][n] 

중 하나 개 배열을 생성 또는 INT의 두 배열을 만들 :

2) int[][] V = new int[m][n] 

3) int[][] P = new int[m][n] 

은 분명히 MyObject 적어도 두 개의 필드와 몇 가지 방법을 포함 . 이제 MyObject 배열을 반복하면서 값을 할당하기 위해 new을 호출해야합니다. 그렇지 않으면 null 포인터 예외가 발생합니다. 이것은 라인 1의 new이 충분하지 않다는 것을 의미합니다. 배열이 Java의 객체이기 때문에 인수가 더 복잡하여 P[i][j]=n보다 비용이 많이 듭니까?

+0

I 생각 예 V는 [I]은 [J]를 새을 MyObject = (오브젝트 1, object2); P [i] [j] = n보다 비싸다. . 그러나 나는 당신이 이것에 대해 너무 진지해야한다고 생각하지 않는다. –

+0

코딩을 시작하기 전에 다른 메모리 레이아웃의 효율성 파악 *이 절대로 작동하지 않습니다. 어느 것이 든, 그리고 그 다음에는 두 가지 방법 중 하나를 코딩해야합니다. 너무 느린 경우 속도가 느려지는지 확인하십시오. 기회는, 그것은 메모리에있는 당신의 물건의 배치와 관련이 없을 것입니다. – dasblinkenlight

+1

관련 : n이 m보다 상당히 크거나 작 으면 http://stackoverflow.com/questions/15339296/memory-usage-of-multidimensional-array-does-the-order-makes-difference – assylias

답변

2

이 인수의 P 위해서,보다 고가의 동작이다 [I] [J] = N, 어레이는 자바 객체 것을 고려? 첫 번째 경우

는 유형 어레이의 다른 오브젝트를 저장하는 배열 객체를 생성한다. 배열 객체와 배열에 저장할 객체를 모두 인스턴스화해야 객체 m * n + 1 객체 인스턴스화와 메모리 사용량이 (m * n + 1) * objectSize이 필요합니다.

두 번째 경우에는 배열 객체를 인스턴스화하기 만하면됩니다. int 프리미티브는 객체가 아니므로 더 빠르고 메모리 효율이 좋고 객체 메모리 크기가 int보다 몇 배 더 커야합니다. 여기서 기본적으로 1 개의 객체 인스턴스화와 (m * n) * intSize + objectSize 메모리 소비가 있습니다.

프리미티브를 사용하는 또 다른 이유는 로컬 변수로 사용될 때 스택에 유지된다는 사실입니다. 계산 된 값을 배열에 저장하기 전에 중간 로컬 변수를 메서드 내에서 사용하고 이러한 변수의 메모리 할당/할당 해제 시간은 힙에있는 객체보다 몇 배 높습니다.

+0

객체 메모리 소비가 실제로 두 가지 프리미티브보다 훨씬 큽니까? 내 이해에 따르면, 개체에 할당 된 공간은 두 개의 기본 필드와 일부 오버 헤드로 구성됩니다. 이것은 http://www.javamex.com/tutorials/memory/object_memory_usage.shtml에 따라입니다. 왜 "몇 배"더 커야합니까? – user2002121

+0

@ user2002121 정수 개체는 네 배 이상의 공간을 차지합니다. Object는 3 배 이상의 공간을 차지할 것으로 예상됩니다 (int가 없으므로) - 신뢰할 수있는 참조를보십시오 : http://www.ibm.com/developerworks/java/library/j-codetoheap/index.html 또한 그는 Object 객체를 아무 것도 사용할 수 없다는 점에 유의했다 (이 경우에는 동기화에 대한 잠금이 예외 임). – m3th0dman

0

우선 배열 대신 java에서 List 또는 Set 즉 컬렉션을 사용해야합니다. 당신이 처리해야하는 데이터의 크기를 알지 못할 수도 있기 때문입니다. 또한 컬렉션에는 요소 삽입이나 삭제와 같은 작업을 쉽게 수행 할 수있는 API 메소드가 있습니다. 배열 작업은 반복적으로 반복해야 할 수도 있기 때문에 매우 복잡하고 오류가 발생하기 쉽습니다. 그리고 가변 크기 데이터를 가지고 있다면 컴파일 시간에 크기를 결정해야하기 때문에 불가능합니다.

또한, 런타임에서 (즉, 새로운 키워드를 사용하여) 메모리를 할당하는 것은 값이 비싸고, 그 값을 이미 존재하는 객체, 즉 p [i] [j] = v;

4

필자는 프로파일 배열을 통해 여러 배열의 스칼라로 객체 배열을 대체하면 메모리 소비와 성능이 향상된다는 사실을 발견했습니다.

그러나 프로파일 링만으로는 귀하의 경우에 그것이 가치있는 최적화인지 여부를 알 수 없습니다.

좋은 프로파일 러를 사용하면 코드의 성능과 메모리 사용 공간을 모두 측정 할 수 있습니다.

1

엄청난 양의 데이터를 빠르게 처리하려면 함께 액세스하는 데이터가 서로 가깝게 데이터를 하나의 인접한 메모리 블록에 배치하는 것이 좋습니다. 이렇게하면 오늘날의 최악의 성능 저하 요인 중 하나 인 캐시 누락을 최소화해야합니다.

자바에서는 프리미티브의 단 하나의 1 차원 배열 만 사용하여이 작업을 수행 할 수 있습니다. 두 개의 배열 또는 심지어 2 차원 배열을 사용하는 경우 데이터는 더 이상 하나의 인접한 블록에 있음을 보장하지 않습니다.

다른

는 다소 더 복잡한 용액, 오프 힙 데이터 구조를 사용하여 여기 같다 : http://mechanical-sympathy.blogspot.com/2012/10/compact-off-heap-structurestuples-in.html