java 코드 에서 instanceof 없애기...

exsider의 이미지

제가 보고 있는 코드중에 다음처럼 구현된게 있습니다.

public void someFunction1(Object obj) {
    if (obj instanceof Integer) {
        // ...
    }
    else if (obj instanceof List) {
        // ...
    }
    else if (obj instanceof Date) {
        // ...
    }
    else if (obj instanceof HashMap) {
        // ...
    }
    else if (obj instanceof Double) {
        // ...
    }
    else {
        // ...
    }
}

Object 객체를 받아 이게 실제 어떤 타입인지 알아본 뒤 그에 맞게 처리합니다. 그런데
저는 이런식으로 if else 를 줄줄이 엮는게 마음에 들지 않습니다. 그래서 HashTable
같은 걸 이용해보려고 했는데요,

public void somFunction2(Object obj) {
    Worker worker = table.get(obj.getClass());
 
    if(work != null) {
        worker.doSomeThing(obj);
    }
    else {
        // ...
    }
}


이렇게 하니 이상없이 잘 동작합니다만, 문제는 속도가 엄청나게 느리더군요.
원래의 것보다 대략 3 ~ 4배정도 느립니다. 속도를 희생하지 않고 코드를 깔끔하게 하는
방법이 없을까요???

kwon37xi의 이미지

그냥...

public void someFunction1(Integer value) {
...
}

public void someFunction1(List list) {
...
}

이런식으로 하면 안되는건가요??

http://kwon37xi.egloos.com

exsider의 이미지

someFunction 은 매개변수로 Object 를 받을 수 밖에 없습니다.
다른 곳에서 객체를 받은 뒤 그걸로 someFunction 을 호출하는데,
문제는 그 '다른 곳'이 Object 객체를 리턴한다는 겁니다.
'다른 곳'을 바꾸면 되겠지만 그랬다간 일이 어마어마하게 커질듯 합니다...

dormael의 이미지

혹시 HashTable에 처음에 다 넣고 나중에는 get만 쓰시는 거라면 HashMap으로 교체하심이 어떨지요?
HashTable은 멀티쓰레드를 고려해 만들어 졌다고 알고 있습니다.

-- Signature --
青い空大好き。
蒼井ソラもっと好き。
파란 하늘 너무 좋아.
아오이 소라 더좋아.

exsider의 이미지

HashMap 을 써보기도 했습니다.
확실히 HashTable 보다는 빠릅니다만, 여전히 원래의 것보다는
2배정도 느리더군요...

dormael의 이미지

여러가지 테스트를 통해서 확인해 보셔야 할것 같습니다.
만일 속도가 매우 중요한 부분이라면요.

hashCode생성과 instanceof의 속도 차이가 확실이 크다면 말씀하신 방식으로는 희생이 커서 쓰기 힘들것 같습니다.

제가 제안해보고 싶은 다른 방법은 그냥 array에 넣어놓고 for문을 돌면서 비교하는거 정도네요.. ^^
그 경우 == 혹은 equals메소드를 쓰게 되므로(obj.getClass()라면 ==도 가능하지 않을까 싶네요.) 최소한 hashCode보다는 빠를것 같습니다.

아, 그리고 속도 테스트는 어떻게 하셨는지 궁금합니다. 경우에 따라서는 테스트를 어떻게 하느냐에 따라 차이가 날수도 있으니까요.

-- Signature --
青い空大好き。
蒼井ソラもっと好き。
파란 하늘 너무 좋아.
아오이 소라 더좋아.

hultul의 이미지

코더에서 프로그래머까지

코더에서 프로그래머까지

다즐링의 이미지

혹시 hashmap 을 어떻게 만드셨는지요?
관련 코드및.. 들어갈 Class가 몇개나 되는지요?

------------------------------------------------------------------------------------------------
Life is in 다즐링

dormael의 이미지

자바 Collections인가 거기 들어가 있는 기본 API를 말한겁니다.
1.3부터인가에는 기본으로 들어가 있는걸로 알고 있습니다. 1.4인가?
정확하지는 않네요.

-- Signature --
青い空大好き。
蒼井ソラもっと好き。
파란 하늘 너무 좋아.
아오이 소라 더좋아.

exsider의 이미지

배열로 해봤더니 원래의 것보다 더 빠르군요... hashmap 을 쓴 것보다
약간 지저분해지기는 하지만 if else 보다는 훨씬 나으니 이쪽을
고려해봐야 겠네요.

다만 문제가 되는게 코드를 분석해보니 일이 좀 복잡해질 것 같네요.
위와 같은 구조가 코드 곳곳에서 독립적으로 쓰이고 각각의 table
크기도 2 ~3 개 에서부터 20여개 이상까지 다양하며 어떤 경우는
더블 디스패치까지 해야 하는군요.

dormael의 이미지

ClassMap같은걸 하나 만들어 보심이?ㅋㅋ
hashCode가 아닌 Object.class를 키로 하는 맵이요.^^
그럼 소스가 좀 나아 지겠네요.

꼭 맵이 아니라도 되구요.

-- Signature --
青い空大好き。
蒼井ソラもっと好き。
파란 하늘 너무 좋아.
아오이 소라 더좋아.

cleol의 이미지

그럼 아예 멀티메소드 라이브러리를 사용해 보시는 것은 어떨까요? 예전에 찾아놨던 녀석인데 실제로 사용해보지는 않아서 얼마나 쓸만한지는 모르겠습니다만 한 번 살펴보시는 것도 좋을 것 같습니다.

http://ovmj.org/polyd/

언어자체에서 멀티메소드를 제공하는 경우에 비해서 코드가 지저분하기는 하지만 어쨌거나 개념적으로 깔끔하고, 런타임에 바이트코드를 생성하니 속도도 그리 나쁘지는 않을 것 같습니다.

다즐링의 이미지

배열이 hashmap 보다 빠른건 당연한거 같군요;

기본적으로 hashmap 에는.. 기본 capacity가 있는데 그게 아마 75인가 할껍니다.

------------------------------------------------------------------------------------------------
Life is in 다즐링

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.