Java
[Java] equals의 활용. 더 나아가 코드 구현의 방법. - 2 -
용식
2010. 7. 30. 00:00
앞서 포스트에서는
결과 값을 List<TestDomain>에 담기로 하였습니다.
그래서 중간 중간 나오는 결과를 List<TestDomain>에 담아 두는 로직이
들어가 있었습니다.
하지만, 그렇기 때문에 이미 합산 된 검색어를 찾기 위해서
다시 List에 대해 loop를 돌면서 해당 검색어를 가진 TestDomain을 찾아야 했습니다.
순차 탐색을 하기 때문에 최대 n만큼의 시간이 소요됩니다.
합산 되는 결과가 많아져서 List<TestDomain>의 크기가 커질 수록
탐색 시간도 길어질 것 입니다.
그러면 이 탐색시간을 줄이면 더욱 속도를 올릴 수 있을 것 같습니다.
여러가지 데이터를 탐색하는 알고리즘 중에서 상당히 빠른 방법이 있습니다.
바로 HashCode를 사용한 방법입니다.
이제 350000개의 7일치 검색어를 loop돌면서 (이건 어쩔 수 없다 치고요..)
각 검색어에 대한 검색 횟수의 합을 구한 후 List<TestDomain>에 넣는 것이 아니라
Map<String,TestDomain>에 넣어두겠습니다.
물론, 모든 결과가 Map<String,TestDomain>에 들어 간 이후에는 이를 다시
List<TestDomain>형으로 변경해줘야 합니다.
List<TestDomain>은 이미 사용되고 있는 메서드의 리턴형이기 때문에
이것이 바뀌게 되면 다른 클래스들을 수정해야하는 일이 생깁니다.
내부에서의 리팩토링만 하고 메서드의 signature는 그대로 유지하는 것입니다.
아무튼, 위와 같은 Map -> List 의 형변환을 하는 것이
불필요한 일일지도 모르겠습니다만..
한번 해보면 알겠죠..^^
Test.java 세번째
결과를 담아서 사용 할 Map객체를 생성하고
이를 사용해서 각 검색어의 검색횟수를 머지하고 있습니다.
결과는
이렇게 나옵니다. 물론 PC마다 조금씩 다르겠지만...
앞선 포스트에서의 여러가지 방법보다 엄청나게 빠른 성능적 향상을 가져 올 수 있었습니다.
ms단위로 떨어졌네요..
가장 먼저 구현되어 있던 Test.java에 비해서
크게 복잡해지지도 않았고, 특별히 다른 라이브러리를 사용하지도 않았습니다.
하지만, 약간의 생각의 전환의 과정을 밟아오면서
조금조금씩 성능을 향상 시킬 수 있었습니다.
포스트를 마무리하기전에
위 내용을 멀티스레드로 구현해보겠습니다.
멀티스레드로 구현하면 더 빠를까요?
KeywordMergetWorker.java
Runnable 인터페이스를 구현한 KeywordMergeWorker입니다.
타겟이 되는 List와 결과를 담을 Map을 생성자에서 받아서
이 List에 대해 일을 하게 됩니다.
사실 여기서는 각각의 List에는 중복된 키워드가 들어있지 않기 때문에
각 KeywordMergeWorker는 단순히 List에 있는 TestDomain을 Map에 담아내는 역할만을
하게 됩니다. 물론 이 KeywordMergeWorker들이 여러개 생성되어 일을 하게 되는 경우에는
상황이 좀 다르겠죠..
그리고 결과를 담을 Map 객체를 병렬처리에 맞게 바꿔줘야 합니다.
각각의 KeywordMergeWorker가 자기의 List에서 TestDomain을 꺼내 위 Map에 있는지 없는지 확인 후
작업을 해야하기 때문에 각 thread간의 동기화가 중요합니다. 인위적으로 synchronized를 사용하는 것 보다는
기본적으로 제공하는 라이브러리를 사용하겠습니다.
각 5만개의 키워드를 가지고 있는 List를 전부 합쳐서 총 350000개의 키워드를 가지고 있던 initDatas도 수정해야 합니다.
각각의 스레드가 동일한 크기의 List를 가지고 일 하도록 하는 것도 병렬처리에서는 중요합니다.
총 7개의 스레드가 일을 한다고 가정 할 때
6개의 스레드가 1초만에 일을 끝내고, 1개의 스레드가 10분동안 일을 해야 한다면
결국 그 프로그램의 실행시간은 10분이 되기 때문입니다.
그리고 initDatas의 형을 List<List<TestDomain>> initDatas = new ArrayList<List<TestDomain>>(); 이렇게 수정하고
각 7일치의 List를 add하여 7개의 스레드가 5만개씩의 키워드 List를 가지고 작업을 할 수 있도록 하겠습니다.
실행부는
이렇게 되겠죠..
제 PC가 쿼드코어이지만 그냥 편의를 위해서
7개의 스레드를 생성하여 돌려보겠습니다
Test.java 병렬처리
병렬처리를 할 때 주의해야 할 것들은 거의 신경쓰지 않은 코드입니다.
내용이 그걸 얘기하려는건 아니니까요..
결과는 어떨까요? 더 빨라졌을까요?
오히려 더 느려졌네요..
여러가지 이유가 있겠죠. CPU에 비해 과하게 많은 스레드라던가
동기화를 하기 위해 소요되는 시간이 더 많다던지 하는...
중요한건 병렬처리가 더 좋다 나쁘다에 대한 얘기가 아니라
정말 간단한 하나의 문제를 가지고도 이렇게 여러가지 생각을 해볼 수 있다는 것 입니다.
결과 값을 List<TestDomain>에 담기로 하였습니다.
그래서 중간 중간 나오는 결과를 List<TestDomain>에 담아 두는 로직이
들어가 있었습니다.
하지만, 그렇기 때문에 이미 합산 된 검색어를 찾기 위해서
다시 List에 대해 loop를 돌면서 해당 검색어를 가진 TestDomain을 찾아야 했습니다.
순차 탐색을 하기 때문에 최대 n만큼의 시간이 소요됩니다.
합산 되는 결과가 많아져서 List<TestDomain>의 크기가 커질 수록
탐색 시간도 길어질 것 입니다.
그러면 이 탐색시간을 줄이면 더욱 속도를 올릴 수 있을 것 같습니다.
여러가지 데이터를 탐색하는 알고리즘 중에서 상당히 빠른 방법이 있습니다.
바로 HashCode를 사용한 방법입니다.
이제 350000개의 7일치 검색어를 loop돌면서 (이건 어쩔 수 없다 치고요..)
각 검색어에 대한 검색 횟수의 합을 구한 후 List<TestDomain>에 넣는 것이 아니라
Map<String,TestDomain>에 넣어두겠습니다.
물론, 모든 결과가 Map<String,TestDomain>에 들어 간 이후에는 이를 다시
List<TestDomain>형으로 변경해줘야 합니다.
List<TestDomain>은 이미 사용되고 있는 메서드의 리턴형이기 때문에
이것이 바뀌게 되면 다른 클래스들을 수정해야하는 일이 생깁니다.
내부에서의 리팩토링만 하고 메서드의 signature는 그대로 유지하는 것입니다.
아무튼, 위와 같은 Map -> List 의 형변환을 하는 것이
불필요한 일일지도 모르겠습니다만..
한번 해보면 알겠죠..^^
Test.java 세번째
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package sort; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.Comparator; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Random; | |
import java.util.Set; | |
/** | |
* @author need4spd, need4spd@cplanet.co.kr, 2010. 7. 28. | |
* | |
*/ | |
public class Test { | |
public static void main(String[] args) { | |
Test test = new Test(); | |
test.runTest(); | |
} | |
public void runTest() { | |
//Data 초기화 | |
List<TestDomain> list_1 = new ArrayList<TestDomain>(); | |
List<TestDomain> list_2 = new ArrayList<TestDomain>(); | |
List<TestDomain> list_3 = new ArrayList<TestDomain>(); | |
List<TestDomain> list_4 = new ArrayList<TestDomain>(); | |
List<TestDomain> list_5 = new ArrayList<TestDomain>(); | |
List<TestDomain> list_6 = new ArrayList<TestDomain>(); | |
List<TestDomain> list_7 = new ArrayList<TestDomain>(); | |
List<TestDomain> initDatas = new ArrayList<TestDomain>(); | |
Random random = new Random(); | |
for(int limit = 0; limit < 7; limit++) { | |
for(int i = 0; i < 50000; i++) { | |
if(limit == 0) { | |
TestDomain testDomain = new TestDomain(String.valueOf(i)); | |
testDomain.setCount(random.nextInt(3000)); | |
list_1.add(testDomain); | |
} else if (limit == 1) { | |
TestDomain testDomain = new TestDomain(String.valueOf(i)); | |
testDomain.setCount(random.nextInt(3000)); | |
list_2.add(testDomain); | |
} else if (limit == 2) { | |
TestDomain testDomain = new TestDomain(String.valueOf(i)); | |
testDomain.setCount(random.nextInt(3000)); | |
list_3.add(testDomain); | |
} else if (limit == 3) { | |
TestDomain testDomain = new TestDomain(String.valueOf(i)); | |
testDomain.setCount(random.nextInt(3000)); | |
list_4.add(testDomain); | |
} else if (limit == 4) { | |
TestDomain testDomain = new TestDomain(String.valueOf(i)); | |
testDomain.setCount(random.nextInt(3000)); | |
list_5.add(testDomain); | |
} else if (limit == 5) { | |
TestDomain testDomain = new TestDomain(String.valueOf(i)); | |
testDomain.setCount(random.nextInt(3000)); | |
list_6.add(testDomain); | |
} else if (limit == 6) { | |
TestDomain testDomain = new TestDomain(String.valueOf(i)); | |
testDomain.setCount(random.nextInt(3000)); | |
list_7.add(testDomain); | |
} | |
} | |
} | |
initDatas.addAll(list_1); | |
initDatas.addAll(list_2); | |
initDatas.addAll(list_3); | |
initDatas.addAll(list_4); | |
initDatas.addAll(list_5); | |
initDatas.addAll(list_6); | |
initDatas.addAll(list_7); | |
System.out.println("initData size : " + initDatas.size()); | |
//Data 초기화 끝. | |
//우선 keyName으로 정렬한다. | |
// Comparator<TestDomain> keyNameCompartor = new Comparator<TestDomain>() { | |
// public int compare(TestDomain o1, TestDomain o2) { | |
// return o1.getkeyName().compareTo(o2.getkeyName()); | |
// } | |
// }; | |
// | |
// Collections.sort(initDatas, keyNameCompartor); | |
long startTime = System.currentTimeMillis(); | |
Map<String,TestDomain> resultMap = new HashMap<String,TestDomain>(); | |
long loopCnt = 0; | |
for(TestDomain initData : initDatas) { | |
if(resultMap.containsKey(initData.getkeyName())) { | |
TestDomain alreadyInput = resultMap.get(initData.getkeyName()); | |
int orgCount = alreadyInput.getCount(); | |
int newCount = initData.getCount(); | |
alreadyInput.setCount(orgCount + newCount); | |
} else { | |
resultMap.put(initData.getkeyName(), initData); | |
} | |
loopCnt++; | |
} | |
long endTime = System.currentTimeMillis(); | |
System.out.println("loopCnt : " + loopCnt); | |
System.out.println("sort........"); | |
Comparator<TestDomain> countCompartor = new Comparator<TestDomain>() { | |
public int compare(TestDomain o1, TestDomain o2) { | |
int o1Cnt = o1.getCount(); | |
int o2Cnt = o2.getCount(); | |
return o2Cnt - o1Cnt; | |
} | |
}; | |
List<TestDomain> resultList = new ArrayList<TestDomain>(); | |
Set<String> keySet = resultMap.keySet(); | |
for(String key : keySet) { | |
resultList.add(resultMap.get(key)); | |
} | |
Collections.sort(resultList, countCompartor); | |
System.out.println("resultList size : " + resultList.size()); | |
System.out.println("resultList : " + resultList); | |
System.out.println("수행시간 : " + (endTime - startTime) / 1000 +"초"); | |
System.out.println("수행시간 : " + (endTime - startTime) + "ms"); | |
} | |
private class TestDomain implements Comparable<TestDomain>{ | |
String keyName = ""; | |
int count = 0; | |
/** | |
* @return the count | |
*/ | |
public int getCount() { | |
return count; | |
} | |
/** | |
* @param count the count to set | |
*/ | |
public void setCount(int count) { | |
this.count = count; | |
} | |
public TestDomain(String keyName) { | |
this.keyName = keyName; | |
} | |
/** | |
* @return the key | |
*/ | |
public String getkeyName() { | |
return keyName; | |
} | |
/** | |
* @param key the key to set | |
*/ | |
public void setkeyName(String keyName) { | |
this.keyName = keyName; | |
} | |
@Override | |
public String toString() { | |
return "keyName : ["+keyName+"], count : [" + count + "]"; | |
} | |
@Override | |
public boolean equals(Object obj) { | |
if (this == obj) | |
return true; | |
if (obj == null) | |
return false; | |
if (getClass() != obj.getClass()) | |
return false; | |
TestDomain other = (TestDomain) obj; | |
String otherKey = other.getkeyName(); | |
String thisKey = getkeyName(); | |
return thisKey.equalsIgnoreCase(otherKey); | |
} | |
/* (non-Javadoc) | |
* @see java.lang.Comparable#compareTo(java.lang.Object) | |
*/ | |
@Override | |
public int compareTo(TestDomain o) { | |
return keyName.compareTo(o.getkeyName()); | |
} | |
} | |
} |
결과를 담아서 사용 할 Map객체를 생성하고
Map<String,TestDomain> resultMap = new HashMap<String,TestDomain>();
이를 사용해서 각 검색어의 검색횟수를 머지하고 있습니다.
결과는
initData size : 350000
loopCnt : 350000
sort........
resultList size : 50000
수행시간 : 0초
수행시간 : 63ms
loopCnt : 350000
sort........
resultList size : 50000
수행시간 : 0초
수행시간 : 63ms
이렇게 나옵니다. 물론 PC마다 조금씩 다르겠지만...
앞선 포스트에서의 여러가지 방법보다 엄청나게 빠른 성능적 향상을 가져 올 수 있었습니다.
ms단위로 떨어졌네요..
가장 먼저 구현되어 있던 Test.java에 비해서
크게 복잡해지지도 않았고, 특별히 다른 라이브러리를 사용하지도 않았습니다.
하지만, 약간의 생각의 전환의 과정을 밟아오면서
조금조금씩 성능을 향상 시킬 수 있었습니다.
포스트를 마무리하기전에
위 내용을 멀티스레드로 구현해보겠습니다.
멀티스레드로 구현하면 더 빠를까요?
KeywordMergetWorker.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//INNER CLASS | |
private class KeywordMergeWorker implements Runnable { | |
private List<TestDomain> targetWorkingList = new ArrayList<TestDomain>(); | |
private Map<String,TestDomain> resultMap = null; | |
public KeywordMergeWorker(List<TestDomain> targetWorkingList, Map<String,TestDomain> resultMap) { | |
this.targetWorkingList = targetWorkingList; | |
this.resultMap = resultMap; | |
} | |
@Override | |
public void run() { | |
long loopCnt = 0; | |
for(TestDomain initData : targetWorkingList) { | |
if(resultMap.containsKey(initData.getkeyName())) { | |
TestDomain alreadyInput = resultMap.get(initData.getkeyName()); | |
int orgCount = alreadyInput.getCount(); | |
int newCount = initData.getCount(); | |
alreadyInput.setCount(orgCount + newCount); | |
} else { | |
resultMap.put(initData.getkeyName(), initData); | |
} | |
loopCnt++; | |
} | |
} | |
} |
Runnable 인터페이스를 구현한 KeywordMergeWorker입니다.
타겟이 되는 List와 결과를 담을 Map을 생성자에서 받아서
이 List에 대해 일을 하게 됩니다.
사실 여기서는 각각의 List에는 중복된 키워드가 들어있지 않기 때문에
각 KeywordMergeWorker는 단순히 List에 있는 TestDomain을 Map에 담아내는 역할만을
하게 됩니다. 물론 이 KeywordMergeWorker들이 여러개 생성되어 일을 하게 되는 경우에는
상황이 좀 다르겠죠..
그리고 결과를 담을 Map 객체를 병렬처리에 맞게 바꿔줘야 합니다.
Map<String,TestDomain> resultMap = new ConcurrentHashMap<String,TestDomain>();
각각의 KeywordMergeWorker가 자기의 List에서 TestDomain을 꺼내 위 Map에 있는지 없는지 확인 후
작업을 해야하기 때문에 각 thread간의 동기화가 중요합니다. 인위적으로 synchronized를 사용하는 것 보다는
기본적으로 제공하는 라이브러리를 사용하겠습니다.
각 5만개의 키워드를 가지고 있는 List를 전부 합쳐서 총 350000개의 키워드를 가지고 있던 initDatas도 수정해야 합니다.
각각의 스레드가 동일한 크기의 List를 가지고 일 하도록 하는 것도 병렬처리에서는 중요합니다.
총 7개의 스레드가 일을 한다고 가정 할 때
6개의 스레드가 1초만에 일을 끝내고, 1개의 스레드가 10분동안 일을 해야 한다면
결국 그 프로그램의 실행시간은 10분이 되기 때문입니다.
그리고 initDatas의 형을 List<List<TestDomain>> initDatas = new ArrayList<List<TestDomain>>(); 이렇게 수정하고
각 7일치의 List를 add하여 7개의 스레드가 5만개씩의 키워드 List를 가지고 작업을 할 수 있도록 하겠습니다.
실행부는
for(int threadCount = 0; threadCount < 7; threadCount++) {
KeywordMergeWorker worker = new KeywordMergeWorker(initDatas.get(threadCount), resultMap);
worker.run();
}
KeywordMergeWorker worker = new KeywordMergeWorker(initDatas.get(threadCount), resultMap);
worker.run();
}
이렇게 되겠죠..
제 PC가 쿼드코어이지만 그냥 편의를 위해서
7개의 스레드를 생성하여 돌려보겠습니다
Test.java 병렬처리
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package semina.secondday.improvecode; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.Comparator; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Random; | |
import java.util.Set; | |
import java.util.concurrent.ConcurrentHashMap; | |
/** | |
* @author need4spd, need4spd@cplanet.co.kr, 2010. 7. 28. | |
* | |
*/ | |
public class Test4 { | |
public static void main(String[] args) throws InterruptedException { | |
Test4 test = new Test4(); | |
test.runTest(); | |
} | |
public void runTest() throws InterruptedException { | |
//Data 초기화 | |
List<TestDomain> list_1 = new ArrayList<TestDomain>(); | |
List<TestDomain> list_2 = new ArrayList<TestDomain>(); | |
List<TestDomain> list_3 = new ArrayList<TestDomain>(); | |
List<TestDomain> list_4 = new ArrayList<TestDomain>(); | |
List<TestDomain> list_5 = new ArrayList<TestDomain>(); | |
List<TestDomain> list_6 = new ArrayList<TestDomain>(); | |
List<TestDomain> list_7 = new ArrayList<TestDomain>(); | |
List<List<TestDomain>> initDatas = new ArrayList<List<TestDomain>>(); | |
Random random = new Random(); | |
for(int limit = 0; limit < 7; limit++) { | |
for(int i = 0; i < 50000; i++) { | |
if(limit == 0) { | |
TestDomain testDomain = new TestDomain(String.valueOf(i)); | |
testDomain.setCount(random.nextInt(3000)); | |
list_1.add(testDomain); | |
} else if (limit == 1) { | |
TestDomain testDomain = new TestDomain(String.valueOf(i)); | |
testDomain.setCount(random.nextInt(3000)); | |
list_2.add(testDomain); | |
} else if (limit == 2) { | |
TestDomain testDomain = new TestDomain(String.valueOf(i)); | |
testDomain.setCount(random.nextInt(3000)); | |
list_3.add(testDomain); | |
} else if (limit == 3) { | |
TestDomain testDomain = new TestDomain(String.valueOf(i)); | |
testDomain.setCount(random.nextInt(3000)); | |
list_4.add(testDomain); | |
} else if (limit == 4) { | |
TestDomain testDomain = new TestDomain(String.valueOf(i)); | |
testDomain.setCount(random.nextInt(3000)); | |
list_5.add(testDomain); | |
} else if (limit == 5) { | |
TestDomain testDomain = new TestDomain(String.valueOf(i)); | |
testDomain.setCount(random.nextInt(3000)); | |
list_6.add(testDomain); | |
} else if (limit == 6) { | |
TestDomain testDomain = new TestDomain(String.valueOf(i)); | |
testDomain.setCount(random.nextInt(3000)); | |
list_7.add(testDomain); | |
} | |
} | |
} | |
initDatas.add(list_1); | |
initDatas.add(list_2); | |
initDatas.add(list_3); | |
initDatas.add(list_4); | |
initDatas.add(list_5); | |
initDatas.add(list_6); | |
initDatas.add(list_7); | |
System.out.println("initData size : " + initDatas.size()); | |
//Data 초기화 끝. | |
long startTime = System.currentTimeMillis(); | |
Map<String,TestDomain> resultMap = new ConcurrentHashMap<String,TestDomain>(); | |
List<Thread> runnedThreads = new ArrayList<Thread>(); | |
for(int threadCount = 0; threadCount < 7; threadCount++) { | |
KeywordMergeWorker worker = new KeywordMergeWorker(initDatas.get(threadCount), resultMap); | |
Thread thd = new Thread(worker); | |
runnedThreads.add(thd); | |
} | |
for(Thread thread : runnedThreads) { | |
thread.start(); | |
} | |
for(Thread thread : runnedThreads) { | |
thread.join(); | |
} | |
long endTime = System.currentTimeMillis(); | |
System.out.println("sort........"); | |
Comparator<TestDomain> countCompartor = new Comparator<TestDomain>() { | |
public int compare(TestDomain o1, TestDomain o2) { | |
int o1Cnt = o1.getCount(); | |
int o2Cnt = o2.getCount(); | |
return o2Cnt - o1Cnt; | |
} | |
}; | |
List<TestDomain> resultList = new ArrayList<TestDomain>(); | |
Set<String> keySet = resultMap.keySet(); | |
for(String key : keySet) { | |
resultList.add(resultMap.get(key)); | |
} | |
Collections.sort(resultList, countCompartor); | |
System.out.println("resultList size : " + resultList.size()); | |
System.out.println("resultList : " + resultList); | |
System.out.println("수행시간 : " + (endTime - startTime) / 1000 +"초"); | |
System.out.println("수행시간 : " + (endTime - startTime) + "ms"); | |
} | |
private class KeywordMergeWorker implements Runnable { | |
private List<TestDomain> targetWorkingList = new ArrayList<TestDomain>(); | |
private Map<String,TestDomain> resultMap = null; | |
public KeywordMergeWorker(List<TestDomain> targetWorkingList, Map<String,TestDomain> resultMap) { | |
this.targetWorkingList = targetWorkingList; | |
this.resultMap = resultMap; | |
} | |
@Override | |
public void run() { | |
long loopCnt = 0; | |
for(TestDomain initData : targetWorkingList) { | |
if(resultMap.containsKey(initData.getkeyName())) { | |
TestDomain alreadyInput = resultMap.get(initData.getkeyName()); | |
int orgCount = alreadyInput.getCount(); | |
int newCount = initData.getCount(); | |
alreadyInput.setCount(orgCount + newCount); | |
} else { | |
resultMap.put(initData.getkeyName(), initData); | |
} | |
loopCnt++; | |
} | |
} | |
} | |
private class TestDomain implements Comparable<TestDomain>{ | |
String keyName = ""; | |
int count = 0; | |
/** | |
* @return the count | |
*/ | |
public int getCount() { | |
return count; | |
} | |
/** | |
* @param count the count to set | |
*/ | |
public void setCount(int count) { | |
this.count = count; | |
} | |
public TestDomain(String keyName) { | |
this.keyName = keyName; | |
} | |
/** | |
* @return the key | |
*/ | |
public String getkeyName() { | |
return keyName; | |
} | |
/** | |
* @param key the key to set | |
*/ | |
public void setkeyName(String keyName) { | |
this.keyName = keyName; | |
} | |
@Override | |
public String toString() { | |
return "keyName : ["+keyName+"], count : [" + count + "]"; | |
} | |
@Override | |
public boolean equals(Object obj) { | |
if (this == obj) | |
return true; | |
if (obj == null) | |
return false; | |
if (getClass() != obj.getClass()) | |
return false; | |
TestDomain other = (TestDomain) obj; | |
String otherKey = other.getkeyName(); | |
String thisKey = getkeyName(); | |
return thisKey.equalsIgnoreCase(otherKey); | |
} | |
/* (non-Javadoc) | |
* @see java.lang.Comparable#compareTo(java.lang.Object) | |
*/ | |
@Override | |
public int compareTo(TestDomain o) { | |
return keyName.compareTo(o.getkeyName()); | |
} | |
} | |
} |
병렬처리를 할 때 주의해야 할 것들은 거의 신경쓰지 않은 코드입니다.
내용이 그걸 얘기하려는건 아니니까요..
결과는 어떨까요? 더 빨라졌을까요?
initData size : 7
sort........
resultList size : 50000
수행시간 : 0초
수행시간 : 125ms
sort........
resultList size : 50000
수행시간 : 0초
수행시간 : 125ms
오히려 더 느려졌네요..
여러가지 이유가 있겠죠. CPU에 비해 과하게 많은 스레드라던가
동기화를 하기 위해 소요되는 시간이 더 많다던지 하는...
중요한건 병렬처리가 더 좋다 나쁘다에 대한 얘기가 아니라
정말 간단한 하나의 문제를 가지고도 이렇게 여러가지 생각을 해볼 수 있다는 것 입니다.