์๋ ํ์ธ์.
์ง๋๋ฒ์ kotlin์ Equality์ ๋ํด ํฌ์คํ ํ์๋๋ฐ์. ์๋ ํฌ์คํ ์ ๋๋ค.
Kotlin์ Equality, == vs ===
Equality | Kotlin kotlinlang.org ๊ณต์๋ฌธ์์ ๋ฐ๋ฅด๋ฉด kotlin์๋ ๋ ๊ฐ์ง ํ์ ์ Equality๊ฐ ์กด์ฌํฉ๋๋ค. Structural equality์ Referential equality์ธ๋ฐ์. ๊ฐ๋จํ ๋งํ์๋ฉด Structural equality๋ ๊ฐ์ ๋น๊ตํ๋ ๊ฒ์ด๊ณ , Ref
dev-sia.tistory.com
Structural equality์ Referential equality, ๋์ผ์ฑ๊ณผ ๋๋ฑ์ฑ์ ๋ํด ์ ๋ฆฌํ๋ฉด์ == ์ฐ์ฐ์์
===
์ฐ์ฐ์์ ์ฐจ์ด์ ๋ํด ์์๋ณด์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ equals๋ฅผ ํธ์ถํ์ ๋ ๋์ผ์ฑ๊ณผ ๋๋ฑ์ฑ์ ๋น๊ตํด ์ฃผ๋ ๊ฒ์ ์ฐจ์ด๋ฅผ ์์๋ณด์์ฃ .
์ฌ๊ธฐ์์ HashSet<List<Int>>๋ ๋๋ฑ์ฑ์ ๋น๊ตํด ์ฃผ๋ฉด์, ์์๋ก ์ฃผ์ด์ง ๋ฆฌ์คํธ๊ฐ ๋์ผํ ํฌ๊ธฐ๋ฉด์ ๋์ผํ ์์๋ฅผ ๋์ผํ ์์๋ก ์ ์ฅํ๊ณ ์๋ค๋ฉด return true๋ก ๋์ํ๋ค๊ณ ๋ง์๋๋ ธ์ต๋๋ค.
๊ทธ๋ฌ๋ HashSet<IntArray>๋ ๋์ผ์ฑ์ ๋น๊ตํด ์ฃผ๋ฉด์, ์๋ฒฝํ ๋๋ฑํ ์์๊ฐ ๋ค์ด์ค๋๋ผ๋ ์ฃผ์๊ฐ์ ํตํด set ๋ด๋ถ ์์ ์ค๋ณต์ ์ฒดํฌํ๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ํ๋ ๋๋ก ๋์ํ์ง ์๋๋ค...๊ณ ๋ง์๋๋ ธ์์ฃ .
๋ง์ง๋ง์ผ๋ก List์ Array๋ ์ฐ์ฐ์ ์๋นํ ์๊ฐ๋ณต์ก๋ ์ฐจ์ด๊ฐ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ List์์๋ง ๋๋ฑ์ฑ์ ๋น๊ตํด ์ฃผ๋ ๊ฒ์ด ์กฐ๊ธ ์์ฝ๋ค๊ณ ์ ๋ฆฌํ์์ต๋๋ค.
๊ทธ๋ฌ๋๋ ์ด๋ ๋ถ์ด ์๋์ ๊ฐ์ ๋๊ธ๋ก ์๊ฒฌ์ ์ฃผ์ จ๋๋ฐ์.
์ค...
์ค๋๋ ฅ์ด ์์ต๋๋ค.
๊ทธ๋์ ์ง์ ํด๋ดค์ต๋๋ค.
๋๋ผ์ด ๊ฒฐ๊ณผ๊ฐ ๋์์ด์.
์คํ
IntArrayWrapper๋ฅผ Set์ ๋ฃ๋ ๊ฒ๊ณผ List<Int>๋ฅผ Set์ ๋ฃ๋ ๊ฒ ์ฌ์ด์ ์๊ฐ ์ฐจ์ด๊ฐ ์์๊น?
์ด๊ฒ ๊ถ๊ธํ์ต๋๋ค.
๊ฒฐ๋ก ๋ง ๋งํด๋ณด์๋ฉด IntArrayWrapper๊ฐ ๋ ๋น ๋ฅธ ๊ฒ์ผ๋ก ์ธก์ ๋์์ต๋๋ค. N์ด ์์ผ๋ฉด ์ฐจ์ด๊ฐ ๊ทผ์ํ๊ธฐ๋ ํ์ง๋ง N์ด ์ปค์ง์๋ก ์ ์๋ฏธํ ์๊ฐ ์ฐจ์ด๊ฐ ์กด์ฌํ๊ธฐ๋ ํ๋๋ผ๊ณ ์.
IntArrayWrapper
class IntArrayWrapper(private val array: IntArray) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is IntArrayWrapper) return false
return array.contentEquals(other.array)
}
override fun hashCode(): Int {
return array.contentHashCode()
}
}
IntArrayWrapper์ ์ฝ๋๋ ์ด๋ ์ต๋๋ค.
equals๋ฅผ ์ค๋ฒ๋ผ์ด๋ํด์
1. ์ฃผ์๊ฐ์ผ๋ก ๋์ผ์ฑ ๋น๊ต
2. ํ์ ๋น๊ต
3. contentEquals๋ก ๋๋ฑ์ฑ ๋น๊ต
๋ฅผ ํด ์ฃผ์์ด์.
๋๋ฑ์ฑ์ผ๋ก ์์๋ฅผ ๊ตฌ๋ณํ๋ ๊ฒ์ด ๋ชฉํ์ด๊ธฐ ๋๋ฌธ์ hashCode ๋ํ contentHashCode๋ก ์ค๋ฒ๋ผ์ด๋ํด ์ฃผ์์ต๋๋ค.
ํ ์คํธ ๋ฐฉ๋ฒ
1. ๋์ผํ ์์: IntWrapperArray์ List<Int>๋ฅผ set์ N๋ฒ ์ถ๊ฐํ๊ธฐ
2. ๋ค๋ฅธ ์์: IntWrapperArray์ List<Int>๋ฅผ set์ N๋ฒ ์ถ๊ฐํ๊ธฐ
1๋ฒ ์ฝ๋
๋์ผํ ์์๋ฅผ set์ N๋ฒ ์ถ๊ฐํ๊ธฐ
import kotlin.system.measureTimeMillis
class IntArrayWrapper(private val array: IntArray) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is IntArrayWrapper) return false
return array.contentEquals(other.array)
}
override fun hashCode(): Int {
return array.contentHashCode()
}
}
fun main() {
val N = 10000000
val setWrapperArray = HashSet<IntArrayWrapper>()
val setOriginList = HashSet<List<Int>>()
// IntArray WrapperClass, set์ N๊ฐ์ ์์ ์ถ๊ฐํ๊ธฐ
val timeWrapperArray = measureTimeMillis {
for (i in 0 until N) {
setWrapperArray.add(IntArrayWrapper(intArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)))
}
}
println(setWrapperArray.size)
println("IntArrayWrapper = $timeWrapperArray")
val timeOriginList = measureTimeMillis {
for (i in 0 until N) {
setOriginList.add(listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
}
}
println(setOriginList.size)
println("List<Int> = $timeOriginList")
var list = mutableListOf<List<Int>>()
val timeOriginListAdd = measureTimeMillis {
for (i in 0 until N) {
list.add(listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
}
}
println(list.size)
println("List<Int> mutableList Add = $timeOriginListAdd")
}
N์ 10000000์ผ๋ก ์ฃผ์์ต๋๋ค.
๋ ํฌ๊ฒ ์ฃผ๋ ค๋ฉด heap ์ต์ ์ ๋ณ๊ฒฝํ์ ์ผ ํ ๋ฏ ํฉ๋๋ค. ์ ๋ 0 ํ๋ ๋ ๋ถ์ด๋๊น ๋ฉ๋ชจ๋ฆฌ๊ฐ ํฐ์ง๋๋ผ๊ณ ์.
์ถฉ๋ถํ ์ ์๋ฏธํ ์๊ฐ ์ฐจ์ด๊ฐ ๋ณด์ด๊ธฐ ๋๋ฌธ์ ๊ตณ์ด ์ต์ ๋ณ๊ฒฝ๊น์ง๋ ํ์ง ์์์ต๋๋ค.
์์ ์ฝ๋๋ฅผ ์คํ์์ผ ๋ณด๋ฉด ์๋์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋์ต๋๋ค.
1
IntArrayWrapper = 385
1
List<Int> = 758
10000000
List<Int> mutableList Add = 1174
์๋ํ๋ ๋๋ก ๋์ํ๋์ง ํ์ธํ๊ธฐ ์ํด size๋ ํจ๊ป ์ถ๋ ฅํด์ฃผ์์ต๋๋ค.
List<Int>๊ฐ ๋ ๋๋ฆฐ ๊ฒ์ผ๋ก ๋์์ต๋๋ค.
์๋ง IntArray๋ ๋ฌผ๋ฆฌ์ ์ผ๋ก ์ฐ์์ ์ธ ๋ฉ๋ชจ๋ฆฌ์ ์์๊ฐ ์ ์ฅ๋๊ณ , List<Int>๋ ๋ ผ๋ฆฌ์ ์ผ๋ก ์ฐ์์ ์ธ ๋ฉ๋ชจ๋ฆฌ์ ์์๊ฐ ์ ์ฅ๋๊ธฐ ๋๋ฌธ์ ๋ค์ ์์๋ก ๋์ด๊ฐ๋ ๋์์ด ์ด๋ฐ ์ฐจ์ด๋ฅผ ๋ง๋ค์ด๋ด์ง ์์์๊น ์ถ๋ค์.
2๋ฒ ์ฝ๋
๋ค๋ฅธ ์์๋ฅผ set์ N๋ฒ ์ถ๊ฐํ๊ธฐ
import kotlin.system.measureTimeMillis
class IntArrayWrapper(private val array: IntArray) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is IntArrayWrapper) return false
return array.contentEquals(other.array)
}
override fun hashCode(): Int {
return array.contentHashCode()
}
}
fun main() {
val N = 10000000
val setWrapperArray = HashSet<IntArrayWrapper>()
val setOriginList = HashSet<List<Int>>()
// IntArray WrapperClass, set์ N๊ฐ์ ์์ ์ถ๊ฐํ๊ธฐ
val timeWrapperArray = measureTimeMillis {
for (i in 0 until N) {
setWrapperArray.add(IntArrayWrapper(intArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, i)))
}
}
println(setWrapperArray.size)
println("IntArrayWrapper = $timeWrapperArray")
val timeOriginList = measureTimeMillis {
for (i in 0 until N) {
setOriginList.add(listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, i))
}
}
println(setOriginList.size)
println("List<Int> = $timeOriginList")
var list = mutableListOf<List<Int>>()
val timeOriginListAdd = measureTimeMillis {
for (i in 0 until N) {
list.add(listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, i))
}
}
println(list.size)
println("List<Int> mutableList Add = $timeOriginListAdd")
}
์ด๋ฒ์๋ ๊ฐ set์ ์์์ ๋ง์ง๋ง๋ง๋ค 10 ๋์ i๋ฅผ ๋ฃ์ด์ฃผ์์ต๋๋ค.
๋ชจ๋ ๋ค๋ฅธ ์์๋ฅผ ๋ฃ์ด์ค ๊ฒ์ด์ฃ .
์์ ์ฝ๋๋ฅผ ์คํ์์ผ ๋ณด๋ฉด ์๋์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋์ต๋๋ค.
10000000
IntArrayWrapper = 1083
10000000
List<Int> = 1577
10000000
List<Int> mutableList Add = 794
size๋ฅผ ๋ณด๋ ์๋ํ๋ ๋๋ก ๋ค ์ ๋ค์ด๊ฐ๊ณ , ์ฌ๊ธฐ์์๋ ์ฝ๊ฐ์ ์๊ฐ ์ฐจ์ด๊ฐ ๋ณด์ด๋ค์.
๋ณธ๊ฒฉ์ ์ผ๋ก ํ๋ณด์๋ฉด N๋ ๋ค์ํ๊ฒ ๋ฃ์ด๋ณด๊ณ ์์๋ ๋ค์ํ๊ฒ ๋ฃ๊ณ ํด์ผ ํ ๊ฒ ๊ฐ์ง๋ง ์ค์ ๋ก ์๊ฐ ์ฐจ์ด๊ฐ ์กด์ฌํ๋ค๋ ๊ฒ์ ๋ช ํํ ๊ฒ ๊ฐ์ต๋๋ค.
์ ๊ธฐํ๋ค์...
์ฝ๋๋ฅผ ๊ธฐ์ตํด์ ์จ๋จน๋๋ค๋ฉด ๋ฆฌ์คํธ์์ ์์์ ๋๋ฑ์ฑ์ ์ฒดํฌํ๊ณ ์ถ์ ๋ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค.
๋ฌผ๋ก IntArrayWrapper๋ ์์ ์ถ๊ฐ๊ฐ ์ด๋ ต๊ณ , List๋ mutableList๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ ์์ ์ถ๊ฐ ๋ฐ ์ญ์ ๊ฐ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ๊ฐ ์ํฉ๋ง๋ค ์ด๋ค ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ ํํ ์ง๋ ๊ฐ๋ฐ์์ ๋ชซ์ ๋๋ค.
'๐ ๊ณต๋ถ > ๐ Kotlin' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Kotlin์ Equality, == vs === (1) | 2023.04.27 |
---|---|
์ฝํ๋ฆฐ ๋๋ฌด ์ฌ๋ฐ๋ค๋ ๊ธ (0) | 2023.04.24 |
Kotlin์์ ์ฝ๋ ์คํ ์๊ฐ ์ฌ๊ธฐ (2) | 2023.02.11 |