API ๋ชจ์์ด ์์ฑ๋์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๋ ์ฌ์ ํ ๊ตฌํ์ ์ฌ์ฉํ ํ๋ณด ๋ชฉ๋ก ์ค์์ ๊ฐ์ฅ ์ข์ ํด์ ์๊ณ ๋ฆฌ์ฆ์ ๊ฒฐ์ ํ๊ณ ์์ผ๋ฉฐ ๊ฐ ์๊ณ ๋ฆฌ์ฆ์ ์ฒ๋ฆฌ๋/๋ถํฌ๋ฅผ ์ธก์ ํ๋ ๋ฐ ๋์์ ์ค ์ฌ๋์ด ํ์ํฉ๋๋ค. ํด๋น ์ญํ ์ ์ํํ๊ณ ์ถ๋ค๋ฉด ์๋์ ๋๊ธ์ ๋จ๊ฒจ์ฃผ์ธ์.
https://github.com/dotnet/corefx/issues/14354#issuecomment -308190321์์ @terrajobst ๊ฐ ์น์ธํ API๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
// Will live in the core assembly
// .NET Framework : mscorlib
// .NET Core : System.Runtime / System.Private.CoreLib
namespace System
{
public struct HashCode
{
public static int Combine<T1>(T1 value1);
public static int Combine<T1, T2>(T1 value1, T2 value2);
public static int Combine<T1, T2, T3>(T1 value1, T2 value2, T3 value3);
public static int Combine<T1, T2, T3, T4>(T1 value1, T2 value2, T3 value3, T4 value4);
public static int Combine<T1, T2, T3, T4, T5>(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5);
public static int Combine<T1, T2, T3, T4, T5, T6>(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6);
public static int Combine<T1, T2, T3, T4, T5, T6, T7>(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7);
public static int Combine<T1, T2, T3, T4, T5, T6, T7, T8>(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7, T8 value8);
public void Add<T>(T value);
public void Add<T>(T value, IEqualityComparer<T> comparer);
[Obsolete("Use ToHashCode to retrieve the computed hash code.", error: true)]
[EditorBrowsable(Never)]
public override int GetHashCode();
public int ToHashCode();
}
}
์ด ์ ์์ ์๋ณธ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ข์ ํด์ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํด ์ถ์
ํ ๋ง๋ฒ ์์๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ ์ฝ๋๋ฅผ ๋นํ์ง ์์๋ ๋ฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ด ๋์์ง๋ง ๊ฐ๊ฒฐํ GetHashCode
๊ตฌํ์ ์์ฑํ๋ ๊ฒ์ด ๋ ์ ํน์ ์ด์ด์ผ ํฉ๋๋ค.
class Person
{
public override int GetHashCode() => FirstName.GetHashCode() + LastName.GetHashCode();
}
ํด์ ์ฝ๋ ์์ฑ์ ์บก์ํํ๊ณ ๊ฐ๋ฐ์๊ฐ ๋ณต์กํ ์ธ๋ถ ์ฌํญ์ ํผ๋๋์ง ์๋๋ก HashCode
์ ํ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค. ๋ค์์ https://github.com/dotnet/corefx/issues/14354#issuecomment -305019329๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ ๋ด ์ ์์ด๋ฉฐ ์ฝ๊ฐ์ ์์ ์ด ํ์ํฉ๋๋ค.
// Will live in the core assembly
// .NET Framework : mscorlib
// .NET Core : System.Runtime / System.Private.CoreLib
namespace System
{
public struct HashCode
{
public static int Combine<T1>(T1 value1);
public static int Combine<T1, T2>(T1 value1, T2 value2);
public static int Combine<T1, T2, T3>(T1 value1, T2 value2, T3 value3);
public static int Combine<T1, T2, T3, T4>(T1 value1, T2 value2, T3 value3, T4 value4);
public static int Combine<T1, T2, T3, T4, T5>(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5);
public static int Combine<T1, T2, T3, T4, T5, T6>(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6);
public static int Combine<T1, T2, T3, T4, T5, T6, T7>(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7);
public static int Combine<T1, T2, T3, T4, T5, T6, T7, T8>(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7, T8 value8);
public void Add<T>(T value);
public void Add<T>(T value, IEqualityComparer<T> comparer);
public void AddRange<T>(T[] values);
public void AddRange<T>(T[] values, int index, int count);
public void AddRange<T>(T[] values, int index, int count, IEqualityComparer<T> comparer);
[Obsolete("Use ToHashCode to retrieve the computed hash code.", error: true)]
public override int GetHashCode();
public int ToHashCode();
}
}
์ด API์ ๋ชฉํ๋ https://github.com/dotnet/corefx/issues/14354#issuecomment -305019329์์ @terrajobst ์ ์๊ฒฌ์ ์ฐธ์กฐํ์ญ์์ค . ๊ทธ์ ๋ง์ ๋ชจ๋ ์ ํจํ๋ค. ๊ทธ๋ฌ๋ ์ ๋ ํนํ ๋ค์์ ์ง์ ํ๊ณ ์ถ์ต๋๋ค.
์ ์: ํด์ ๋ฌด์์ํ ์ง์ ์ถ๊ฐ
public static HashCode Randomized<T> { get; } // or CreateRandomized<T>
or
public static HashCode Randomized(Type type); // or CreateRandomized(Type type)
T
๋๋ Type type
๋ ๋์ผํ ์ ํ์ ๋ํด ๋์ผํ ๋ฌด์์ ํด์๋ฅผ ์ป๋ ๋ฐ ํ์ํฉ๋๋ค.
์ ์: ์ปฌ๋ ์ ์ง์ ์ถ๊ฐ
public HashCode Combine<T>(T[] values);
public HashCode Combine<T>(T[] values, IEqualityComparer<T> comparer);
public HashCode Combine<T>(Span<T> values);
public HashCode Combine<T>(Span<T> values, IEqualityComparer<T> comparer);
public HashCode Combine<T>(IEnumerable<T> values);
public HashCode Combine<T>(IEnumerable<T> IEqualityComparer<T> comparer);
๋ค์ ์ฝ๋ HashCode.Empty.Combine(_field1).Combine(_field2).Combine(_field3).Combine(_field4).Combine(_field5);
๋ Combine ํธ์ถ ์์ด ์ธ๋ผ์ธ ์ต์ ํ๋์ด์ผ ํ๊ธฐ ๋๋ฌธ์ Combine(_field1, _field2, _field3, _field4, _field5)
์ค๋ฒ๋ก๋๊ฐ ํ์ํ์ง ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
@AlexRadch
์ ์: ์ปฌ๋ ์ ์ง์ ์ถ๊ฐ
์, ๊ทธ๊ฒ์ ์ด ์ ์์ ๋ํ ๋์ ์ต์ข ๊ณํ์ ์ผ๋ถ์์ต๋๋ค. ํ์ง๋ง ์ด๋ฌํ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๊ธฐ ์ ์ API๊ฐ ์ด๋ป๊ฒ ์๊ฒผ๋์ง์ ์ด์ ์ ๋ง์ถ๋ ๊ฒ์ด ์ค์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๊ทธ๋ coreclr์ ๋ฌธ์์ด์ ์ฌ์ฉ๋๋ Marvin32 ํด์์ ๊ฐ์ ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๊ธฐ๋ฅผ ์ํ์ต๋๋ค. ์ด๋ฅผ ์ํด์๋ HashCode์ ํฌ๊ธฐ๋ฅผ 8๋ฐ์ดํธ๋ก ํ์ฅํด์ผ ํฉ๋๋ค.
๋ด๋ถ์ ์ผ๋ก 4๋ฐ์ดํธ ๋๋ 8๋ฐ์ดํธ ๊ฐ์น์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ Hash32 ๋ฐ Hash64 ์ ํ์ ์ฌ์ฉํ๋ ๊ฒ์ ์ด๋ป์ต๋๊น? ๊ฐ๊ฐ์ ์ฅ๋จ์ ์ ๋ฌธ์ํํ์ญ์์ค. Hash64๋ X์ ์ ํฉํ์ง๋ง ์ ์ฌ์ ์ผ๋ก ๋๋ฆฝ๋๋ค. Hash32๋ ๋ ๋น ๋ฅด์ง๋ง ์ ์ฌ์ ์ผ๋ก ๋ถ์ฐ๋์ง ์์ ์ ์์ต๋๋ค(๋๋ ์ค์ ๋ก ํธ๋ ์ด๋์คํ๊ฐ ๋ฌด์์ด๋ ).
๊ทธ๋ ํด์ ์๋๋ฅผ ๋ฌด์์๋ก ์ง์ ํ๊ธฐ๋ฅผ ์ํ๊ธฐ ๋๋ฌธ์ ํด์๊ฐ ๊ฒฐ์ ์ ์ด์ง ์์์ต๋๋ค.
์ด๊ฒ์ ์ ์ฉํ ๋์์ฒ๋ผ ๋ณด์ ๋๋ค. ๊ทธ๋ฌ๋ ๋๋ ์ด๊ฒ์ ํต์ ํ๋ ค๋ ์ฌ๋๋ค์ ๋ณผ ์ ์์์ต๋๋ค. ๋ฐ๋ผ์ ์๋ง๋ Hash๋ฅผ ์์ฑํ๋ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ด์ผ ํฉ๋๋ค. ํ๋๋ ์๋๋ฅผ ์ฌ์ฉํ์ง ์๊ณ (๊ทธ๋ฆฌ๊ณ ์์์ ์๋๋ฅผ ์ฌ์ฉํจ) ์๋๋ฅผ ์ ๊ณตํ๋๋ก ํ์ฉํ๋ ๊ฒ์ ๋๋ค.
์ฐธ๊ณ : Roslyn์ ์ด๊ฒ์ด Fx์์ ์ ๊ณต๋ ์ ์๋ค๋ฉด ๋งค์ฐ ์ข์ํ ๊ฒ์ ๋๋ค. ์ฌ์ฉ์๋ฅผ ์ํด GetHashCode๋ฅผ ๋ด๋ณด๋ด๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ณ ์์ต๋๋ค. ํ์ฌ ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค.
c#
public override int GetHashCode()
{
var hashCode = -1923861349;
hashCode = hashCode * -1521134295 + this.b.GetHashCode();
hashCode = hashCode * -1521134295 + this.i.GetHashCode();
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(this.s);
return hashCode;
}
์ด๊ฒ์ ์ข์ ๊ฒฝํ์ด ์๋๋ฉฐ ๋ง์ ์ถ์ ํ ๊ฐ๋ ์ ๋ ธ์ถํฉ๋๋ค. ๋์ ํธ์ถํ ์ ์๋ Hash.Whatever API๊ฐ ์์ผ๋ฉด ๊ธฐ์ ๊ฒ์ ๋๋ค.
๊ฐ์ฌ ํด์!
MurmurHash๋ ์ด๋ป์ต๋๊น? ๊ทธ๊ฒ์ ํฉ๋ฆฌ์ ์ผ๋ก ๋น ๋ฅด๋ฉฐ ๋งค์ฐ ์ข์ ํด์ฑ ์์ฑ์ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๋ํ 32๋นํธ ํด์๋ฅผ ๋ด๋ณด๋ด๋ ๊ตฌํ๊ณผ 128๋นํธ ํด์๋ฅผ ๋ด๋ณด๋ด๋ ๊ตฌํ์ ๋ ๊ฐ์ง ๊ตฌํ์ด ์์ต๋๋ค.
32๋นํธ ๋ฐ 128๋นํธ ํ์ ๋ชจ๋์ ๋ํ ๋ฒกํฐํ๋ ๊ตฌํ๋ ์์ต๋๋ค.
@tannergooding MurmurHash๋ ์ด ๋ธ๋ก๊ทธ ๊ฒ์๋ฌผ ์ ์๋ฆฌ์์ ๋ณผ ๋ ๋น ๋ฅด์ง๋ง ์์ ํ์ง ์์ต๋๋ค.
@jkotas , ์๋ ์ ์ฐ๋ฆฌ๊ฐ ๋ ผ์ํ ์ดํ๋ก 32๋นํธ์์ >4๋ฐ์ดํธ ๊ตฌ์กฐ์ฒด์ ๋ํด ๋ ๋์ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ๊ณผ ๊ด๋ จํ์ฌ JIT์์ ์์ ์ด ์์์ต๋๊น? ๋ํ @CyrusNajmabadi ์ ์ ์์ ๋ํด ์ด๋ป๊ฒ ์๊ฐ
๋ด๋ถ์ ์ผ๋ก 4๋ฐ์ดํธ ๋๋ 8๋ฐ์ดํธ ๊ฐ์น์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ Hash32 ๋ฐ Hash64 ์ ํ์ ์ฌ์ฉํ๋ ๊ฒ์ ์ด๋ป์ต๋๊น? ๊ฐ๊ฐ์ ์ฅ๋จ์ ์ ๋ฌธ์ํํ์ญ์์ค. Hash64๋ X์ ์ ํฉํ์ง๋ง ์ ์ฌ์ ์ผ๋ก ๋๋ฆฝ๋๋ค. Hash32๋ ๋ ๋น ๋ฅด์ง๋ง ์ ์ฌ์ ์ผ๋ก ๋ถ์ฐ๋์ง ์์ ์ ์์ต๋๋ค(๋๋ ์ค์ ๋ก ํธ๋ ์ด๋์คํ๊ฐ ๋ฌด์์ด๋ ).
๋๋ ์ฌ์ ํ ์ด ์ ํ์ด ๊ฐ๋ฐ์์๊ฒ ์ ๊ณตํ๊ธฐ์ ๋งค์ฐ ๊ฐ์น๊ฐ ์๊ณ 2.0์ ํฌํจํ๋ ๊ฒ์ด ์ข์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
@jamesqo , ๋๋ ์ด ๊ตฌํ์ด ์ํธํ์ ์ผ๋ก ์์ ํ ํ์๊ฐ ์๋ค๊ณ ์๊ฐํ์ง ์์ต๋๋ค(์ฆ, ๋ช ์์ ์ํธํ์ ํด์ฑ ๊ธฐ๋ฅ์ ๋ชฉ์ ).
๋ํ ํด๋น ๊ธฐ์ฌ๋ Murmur2์ ์ ์ฉ๋ฉ๋๋ค. Murmur3 ์๊ณ ๋ฆฌ์ฆ์์ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์์ต๋๋ค.
์๋ ๋ ผ์ ์ดํ 32๋นํธ์์ >4๋ฐ์ดํธ ๊ตฌ์กฐ์ฒด์ ๋ํ ๋ ๋์ ์ฝ๋ ์์ฑ์ ๊ดํ JIT
๋๋ ์๋ฌด๊ฒ๋ ๋ชจ๋ฅธ๋ค.
@CyrusNajmabadi ์ ์ ์์ ๋ํด ์ด๋ป๊ฒ ์๊ฐ
ํ๋ ์์ํฌ ์ ํ์ 95% ์ด์์ ๊ฒฝ์ฐ์ ์ ์๋ํ๋ ๊ฐ๋จํ ์ ํ์ด์ด์ผ ํฉ๋๋ค. ๊ฐ์ฅ ๋น ๋ฅธ ๊ฒ์ ์๋์ง๋ง ๊ด์ฐฎ์ต๋๋ค. Hash32์ Hash64 ์ค ํ๋๋ฅผ ์ ํํ๋ผ๋ ๊ฒ์ ๊ฐ๋จํ ์ ํ์ด ์๋๋๋ค.
๊ด์ฐฎ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๋ ์ ์ด๋ ๊ทธ 95%์ ๊ฒฝ์ฐ์ ๋ํด ์ถฉ๋ถํ ์ข์ ์๋ฃจ์ ์ ๊ฐ์ง ์ ์์ต๋๊น? ์ง๊ธ์ ์๋ฌด๊ฒ๋ ์์ต๋๋ค... :-/
ํด์์ฝ๋ = ํด์์ฝ๋ * -1521134295 + EqualityComparer
.Default.GetHashCode(this.s);
@CyrusNajmabadi ์ this.s.GetHashCode()๊ฐ ์๋๋ผ EqualityComparer๋ฅผ ์ฌ๊ธฐ์์ ํธ์ถํฉ๋๊น?
๊ตฌ์กฐ์ฒด๊ฐ ์๋ ๊ฒฝ์ฐ: null์ ํ์ธํ ํ์๊ฐ ์๋๋ก ํฉ๋๋ค.
์ด๋ ๋ฐฐํ์์ ์ต๋ช ์ ํ์ ๋ํด์๋ ์์ฑํ๋ ๊ฒ๊ณผ ์ ์ฌํฉ๋๋ค. ์ฌ์ฉ์์๊ฒ ๋ ๋ง์กฑ์ค๋ฌ์ด ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํด ์๋ ค์ง null์ด ์๋ ๊ฐ์ ๊ฒฝ์ฐ๋ฅผ ์ต์ ํํฉ๋๋ค. ํ์ง๋ง ์ด๋ฅผ ์ํ API๊ฐ ๋ด์ฅ๋์ด ์์ผ๋ฉด ์ข์ ๊ฒ์ ๋๋ค.
EqualityComparer.Default.GetHashCode์ ๋ํ ํธ์ถ์ null ๊ฒ์ฌ๋ณด๋ค 10๋ฐฐ ์ด์ ๋ ๋น์๋๋ค... .
EqualityComparer.Default.GetHashCode์ ๋ํ ํธ์ถ์ null ๊ฒ์ฌ๋ณด๋ค 10๋ฐฐ ์ด์ ๋ ๋น์๋๋ค.
๋ฌธ์ ์ฒ๋ผ ๋ค๋ฆฝ๋๋ค. ์ข์ ํด์ ์ฝ๋ API๋ง ์๋ค๋ฉด ๋ด๊ฐ ๋งก์ ์ ์๋ Fx๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค. :)
(๋ํ ์ฐ๋ฆฌ๋ ์ต๋ช ์ ํ์์ ๊ทธ ๋ฌธ์ ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๊ทธ๊ฒ์ด ์ฐ๋ฆฌ๊ฐ ๊ฑฐ๊ธฐ์์๋ ์์ฑํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค).
์ฐ๋ฆฌ๊ฐ ํํ์ ๋ํด ๋ฌด์์ ํ๋์ง ํ์คํ์ง ์์ง๋ง ๋น์ทํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ฐ๋ฆฌ๊ฐ ํํ์ ๋ํด ๋ฌด์์ ํ๋์ง ํ์คํ์ง ์์ง๋ง ๋น์ทํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
System.Tuple
๋ ์ญ์ฌ์ ์ธ ์ด์ ๋ก EqualityComparer<Object>.Default
๋ฅผ ํต๊ณผํฉ๋๋ค. System.ValueTuple
๋ null ๊ฒ์ฌ๋ก Object.GetHashCode๋ฅผ ํธ์ถํฉ๋๋ค( https://github.com/dotnet/coreclr/blob/master/src/mscorlib/shared/System/ValueTuple.cs#L809).
์ ๋ผ. ํํ์ด "HashHelpers"๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ฌ์ฉ์๊ฐ ๋์ผํ ํํ์ ๋ฐ์ ์ ์๋๋ก ๋ ธ์ถ๋ ์ ์์ต๋๊น?
์์ฒญ๋. ๋น์ทํ ์ผ์ ํ๊ฒ ๋์ด ๊ธฐ์ฉ๋๋ค. ๋๋ ์ฐ๋ฆฌ์ ์ต๋ช ์ ํ์ด ํฉ๋ฆฌ์ ์ธ ๋ชจ๋ฒ ์ฌ๋ก๋ผ๊ณ ์๊ฐํ๊ธฐ ๋๋ฌธ์ ์ต๋ช ์ ํ์์ ์์ํ์ต๋๋ค. ๊ทธ๋ ์ง ์๋ค๋ฉด ๊ด์ฐฎ์ต๋๋ค. :)
ํ์ง๋ง ๊ทธ๊ฒ์ด ๋ด๊ฐ ์ฌ๊ธฐ ์๋ ์ด์ ๊ฐ ์๋๋๋ค. ์ ๋ ์ค์ ๋ก ํด์๋ฅผ ํจ๊ณผ์ ์ผ๋ก ๊ฒฐํฉํ๋ ์์คํ ์ ์ป๊ธฐ ์ํด ์์ต๋๋ค. ๊ทธ๊ฒ์ด ์ ๊ณต๋ ์ ์๋ค๋ฉด ์ฐ๋ฆฌ๋ ๋์๋ฅผ ํ๋์ฝ๋ฉํ๊ณ ํด์ ๊ฐ์ ์ง์ ๊ฒฐํฉํ๋ ๋์ ๊ธฐ๊บผ์ด ํธ์ถํ ๊ฒ์ ๋๋ค.
์ปดํ์ผ๋ฌ๊ฐ ์์ฑํ ์ฝ๋์ ๊ฐ์ฅ ์ ํฉํ๋ค๊ณ ์๊ฐํ๋ API ํํ๋ ๋ฌด์์ ๋๊น?
๋ง ๊ทธ๋๋ก ์ด์ ์ ์ ์๋ 32๋นํธ ์๋ฃจ์ ์ค ์ด๋ ๊ฒ์ด๋ ์ ์๊ฒ๋ ๊ด์ฐฎ์ ๊ฒ์ ๋๋ค. ์ ์ฅ, 64๋นํธ ์๋ฃจ์ ์ ๊ด์ฐฎ์ต๋๋ค. "๋๋ ์ผ์ข ์ ํฉ๋ฆฌ์ ์ธ ๋ฐฉ์์ผ๋ก ํด์๋ฅผ ๊ฒฐํฉํ๊ณ ํฉ๋ฆฌ์ ์ผ๋ก ๋ถํฌ๋ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค"๋ผ๊ณ ๋งํ๋ ์ผ์ข ์ API์ ๋๋ค.
๋๋ ๋ค์ ์ง์ ์ ์กฐํ์ํฌ ์ ์์ต๋๋ค.
ํฌ๊ธฐ๊ฐ 4๋ฐ์ดํธ์ธ ๋ณ๊ฒฝํ ์ ์๋ HashCode ๊ตฌ์กฐ์ฒด๊ฐ ์์ต๋๋ค. ์ฌ๊ธฐ์๋ DJBX33X์ ๊ฐ์ ์๊ณ ๋ฆฌ์ฆ์ ํตํด ์ ๊ณต๋ ํด์ ์ฝ๋์ ์์ฒด ํด์ ์ฝ๋๋ฅผ ํผํฉํ์ฌ ์๋ก์ด HashCode๋ฅผ ๋ฐํํ๋ Combine(int) ๋ฉ์๋๊ฐ ์์ต๋๋ค.
@jkotas ๋ DJBX33X์ ๊ฐ์ ์๊ณ ๋ฆฌ์ฆ์ด ์ถฉ๋ถํ ๊ฐ๋ ฅํ๋ค๊ณ ์๊ฐํ์ง ์์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ
ํ๋ ์์ํฌ ์ ํ์ 95% ์ด์์ ๊ฒฝ์ฐ์ ์ ์๋ํ๋ ๊ฐ๋จํ ์ ํ์ด์ด์ผ ํฉ๋๋ค.
95%์ ๊ฒฝ์ฐ์ ์ถฉ๋ถํ ์ ์๋ํ๋ ๊ฐ๋จํ 32๋นํธ ๋์ ํด์๋ฅผ ์๊ฐํด๋ผ ์ ์์ต๋๊น? ์ฌ๊ธฐ์ ์ ์ฒ๋ฆฌ๋์ง ์๋ ๊ฒฝ์ฐ๋ ๋ฌด์์ด๋ฉฐ, 95%์ ๊ฒฝ์ฐ๋ผ๊ณ ์๊ฐํ๋ ์ด์ ๋ ๋ฌด์์ ๋๊น?
@jkotas , ์ฑ๋ฅ์ด ์ด ์ ํ์ ์ ๋ง ์ค์ํฉ๋๊น? ๋๋ ํด์ ํ ์ด๋ธ ์กฐํ์ ๊ฐ์ ํ๊ท ๊ฒ๋ค์ ์๊ฐ ์ด ๋ช ๊ตฌ์กฐ์ฒด ๋ณต์ฌ๋ณด๋ค ํจ์ฌ ๋ ๋ง์ ์๊ฐ์ด ๊ฑธ๋ฆด ๊ฒ์ ๋๋ค. ๋ณ๋ชฉ ํ์์ผ๋ก ํ๋ช ๋๋ฉด ์๋ฌด๋ ์ต์ ํ ์์ ์ ํ์ง ์์ ๋ ์ด API๋ฅผ ์ฐจ๋จํ๋ ๊ฒ๋ณด๋ค API๊ฐ ๋ฆด๋ฆฌ์ค๋ ํ 32๋นํธ ๊ตฌ์กฐ์ฒด ๋ณต์ฌ๋ณธ์ ์ต์ ํํ๋๋ก JIT ํ์ ์์ฒญํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ ๋๊น? ์ฌ๋ณธ?
95%์ ๊ฒฝ์ฐ์ ์ถฉ๋ถํ ์ ์๋ํ๋ ๊ฐ๋จํ 32๋นํธ ๋์ ํด์๋ฅผ ์๊ฐํด๋ผ ์ ์์ต๋๊น?
์ฐ๋ฆฌ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฌธ์์ด์ ๋ํ 32๋นํธ ๋์ ํด์๋ฅผ ์ฌํ๊ฒ ํ์ ์์ผ๋ฉฐ ์ด๊ฒ์ด .NET Core์ ๋ฌธ์์ด์ ๋ํ Marvin ํด์ - https://github.com/dotnet/corert/blob/87e58839d6629b5f90777f886a2f52d7a99c076f/s src/System/Marvin.cs#L25. ๋๋ ์ฐ๋ฆฌ๊ฐ ์ฌ๊ธฐ์ ๊ฐ์ ์ค์๋ฅผ ๋ฐ๋ณตํ๊ณ ์ถ์ง ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
@jkotas , ์ฑ๋ฅ์ด ์ด ์ ํ์ ์ ๋ง ์ค์ํฉ๋๊น?
์ฑ๋ฅ์ด ์ค์ํ๋ค๊ณ ์๊ฐํ์ง ์์ต๋๋ค. ์ด API๊ฐ ์๋ ์์ฑ ์ปดํ์ผ๋ฌ ์ฝ๋์์ ์ฌ์ฉ๋ ๊ฒ ๊ฐ๊ธฐ ๋๋ฌธ์ ๋ณด์ด๋ ๊ฒ๋ณด๋ค ์์ฑ๋ ๋ ์์ ์ฝ๋๋ฅผ ์ ํธํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ ์ฐฝํ์ง ์์ ํจํด์ ๋ ์์ ์ฝ๋์ ๋๋ค.
์ฐ๋ฆฌ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฌธ์์ด์ ๋ํ 32๋นํธ ๋์ ํด์๋ก ์ธํด ์ฌํ๊ฒ ํ์์ ์ ์์ต๋๋ค.
95%์ ๊ฒฝ์ฐ๋ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ค๋๋ ์๋์ผ๋ก ์์ ์ ์ํํ๋ ๋ชจ๋ ์ ํ์ ๋ํด "์ถฉ๋ถํ ์ข์" ํด์๋ฅผ ์ํ๋ ์ผ๋ฐ ๊ฐ๋ฐ์์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์ต๋๋ค.
์ด API๊ฐ ์๋ ์์ฑ ์ปดํ์ผ๋ฌ ์ฝ๋์์ ์ฌ์ฉ๋ ๊ฒ ๊ฐ๊ธฐ ๋๋ฌธ์ ๋ณด์ด๋ ๊ฒ๋ณด๋ค ์์ฑ๋ ๋ ์์ ์ฝ๋๋ฅผ ์ ํธํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ ์ฐฝํ์ง ์์ ํจํด์ ๋ ์์ ์ฝ๋์ ๋๋ค.
์ด๊ฒ์ Roslyn ์ปดํ์ผ๋ฌ์์ ์ฌ์ฉํ์ง ์์ต๋๋ค. ์ด๊ฒ์ ์ฌ์ฉ์๊ฐ ํด๋น ์ ํ์ ๋ํด GetHashCode๋ฅผ ์์ฑํ๋๋ก ๋์ธ ๋ Roslyn IDE์์ ์ฌ์ฉํ๊ธฐ ์ํ ๊ฒ์ ๋๋ค. ์ด๊ฒ์ ์ฌ์ฉ์๊ฐ ๋ณด๊ณ ์ ์งํด์ผ ํ๋ ์ฝ๋์ด๋ฉฐ ๋ค์๊ณผ ๊ฐ์ด ํฉ๋ฆฌ์ ์ ๋๋ค.
```c#
๋ฐํ Hash.Combine(this.A?.GetHashCode() ?? 0,
this.B?.GetHashCode() ?? 0,
this.C?.GetHashCode() ?? 0);
is a lot nicer than a user seeing and having to maintain:
```c#
var hashCode = -1923861349;
hashCode = hashCode * -1521134295 + this.b.GetHashCode();
hashCode = hashCode * -1521134295 + this.i.GetHashCode();
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(this.s);
return hashCode;
๋ด ๋ง์, ์ฐ๋ฆฌ๋ ์ด๋ฏธ Fx์ ์ด ์ฝ๋๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค:
์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ด ํํ์ ์ถฉ๋ถํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์์ ์ ์ ํ์ ๋ํด ์ํ๋ ์ฌ์ฉ์๊ฐ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ ๊ฒ์ด ์ ๊ทธ๋ ๊ฒ ๋ฌธ์ ๊ฐ ๋ ์ง ๋์๊ฒ๋ ๋ถ๋ช ํ์ง ์์ต๋๋ค.
์ฐธ๊ณ : roslyn์์ ์ด ์์ ์ ์ํํ๋ ๊ฒ๋ ๊ณ ๋ คํ์ต๋๋ค.
c#
return (this.A, this.B, this.C).GetHashCode();
ํ์ง๋ง ์ง๊ธ ๋น์ ์ ์ฌ๋๋ค์ด ์ผ์ข ์ ํฉ๋ฆฌ์ ์ธ ๊ธฐ๋ณธ ํด์ฑ ๋์์ ์ป๊ธฐ ์ํด (์ ์ฌ์ ์ผ๋ก ํฐ) ๊ตฌ์กฐ์ฒด๋ฅผ ์์ฑํ๋๋ก ๊ฐ์ํ๊ณ ์์ต๋๋ค.
์ฐ๋ฆฌ๋ ์ค๋๋ ์๋์ผ๋ก ์์ ์ ์ํํ๋ ๋ชจ๋ ์ ํ์ ๋ํด "์ถฉ๋ถํ ์ข์" ํด์๋ฅผ ์ํ๋ ์ผ๋ฐ ๊ฐ๋ฐ์์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์ต๋๋ค.
์๋ ๋ฌธ์์ด ํด์๋ ์ผ๋ฐ ๊ฐ๋ฐ์์๊ฒ ์ ์๋ํ๋ "์ถฉ๋ถํ ์ข์" ํด์์์ต๋๋ค. ๊ทธ๋ฌ๋ ASP.NET ์น ์๋ฒ๋ ์์ ๋ ๋ด์ฉ์ ํด์ ํ ์ด๋ธ์ ์ ์ฅํ๋ ๊ฒฝํฅ์ด ์๊ธฐ ๋๋ฌธ์ DoS ๊ณต๊ฒฉ์ ์ทจ์ฝํ๋ค๋ ๊ฒ์ด ๋ฐ๊ฒฌ๋์์ต๋๋ค. ๋ฐ๋ผ์ "์ถฉ๋ถํ ์ข์" ํด์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋์ ๋ณด์ ๋ฌธ์ ๋ก ๋ฐ๋์์ต๋๋ค.
์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ด ํํ์ ์ถฉ๋ถํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ฐ๋์ ์๋๋๋ค. ๋์ค์ ์๊ณ ๋ฆฌ์ฆ์ ์์ ํ ์ ์๋ ์ต์ ์ ์ ๊ณตํ๋ ํด์ ์ฝ๋๋ฅผ ๋ฌด์์๋ก ๋ง๋ค๊ธฐ ์ํด ํํ์ ๋ํ ๋ฐฑ์คํฑ ์กฐ์น๋ฅผ ๋ง๋ค์์ต๋๋ค.
return Hash.Combine(this.A?.GetHashCode() ?? 0, this.B?.GetHashCode() ?? 0, this.C?.GetHashCode() ?? 0);
์ด๊ฒ์ ๋์๊ฒ ํฉ๋ฆฌ์ ์ผ๋ก ๋ณด์ ๋๋ค.
๋๋ ๋น์ ์ ์์น๋ฅผ โโ์ดํดํ์ง ๋ชปํฉ๋๋ค. ๋ ๊ฐ์ง๋ฅผ ๋ง์ํ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
์๋ ๋ฌธ์์ด ํด์๋ ์ผ๋ฐ ๊ฐ๋ฐ์์๊ฒ ์ ์๋ํ๋ "์ถฉ๋ถํ ์ข์" ํด์์์ต๋๋ค. ๊ทธ๋ฌ๋ ASP.NET ์น ์๋ฒ๋ ์์ ๋ ๋ด์ฉ์ ํด์ ํ ์ด๋ธ์ ์ ์ฅํ๋ ๊ฒฝํฅ์ด ์๊ธฐ ๋๋ฌธ์ DoS ๊ณต๊ฒฉ์ ์ทจ์ฝํ๋ค๋ ๊ฒ์ด ๋ฐ๊ฒฌ๋์์ต๋๋ค. ๋ฐ๋ผ์ "์ถฉ๋ถํ ์ข์" ํด์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋์ ๋ณด์ ๋ฌธ์ ๋ก ๋ฐ๋์์ต๋๋ค.
์๊ฒ ์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด ๋ณด์/DoS ๋ฌธ์ ๊ฐ ์๋ ์ฌ๋๋ค์๊ฒ ์ข์ ํด์ ์ฝ๋๋ฅผ ์ ๊ณตํ๊ฒ ์ต๋๋ค.
ํ๋ ์์ํฌ ์ ํ์ 95% ์ด์์ ๊ฒฝ์ฐ์ ์ ์๋ํ๋ ๊ฐ๋จํ ์ ํ์ด์ด์ผ ํฉ๋๋ค.
์, ๊ทธ๋ ๋ค๋ฉด 95%์ ๊ฒฝ์ฐ์ ์ถฉ๋ถํ ํด์ ์ฝ๋๋ฅผ ์ ๊ณตํ๊ฒ ์ต๋๋ค. ๋ณด์/DoS ๋ฌธ์ ๊ฐ ์๋ ์ฌ๋์ ํด๋น ๋ชฉ์ ์ผ๋ก ๋ฌธ์ํ๋ ํน์ ์์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ฐ๋์ ์๋๋๋ค. ๋์ค์ ์๊ณ ๋ฆฌ์ฆ์ ์์ ํ ์ ์๋ ์ต์ ์ ์ ๊ณตํ๋ ํด์ ์ฝ๋๋ฅผ ๋ฌด์์๋ก ๋ง๋ค๊ธฐ ์ํด ํํ์ ๋ํ ๋ฐฑ์คํฑ ์กฐ์น๋ฅผ ๋ง๋ค์์ต๋๋ค.
ํ์ธ. ์ฌ์ฉ์ ๊ฐ ๋์ผํ ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉํ ์ ์๋๋ก ๋ ธ์ถํ ์ ์์ต๋๊น?
--
"๋ณดํธ์ ์ธ ์๋ฃจ์
์ ๋ง๋ค ์ ์๊ธฐ ๋๋ฌธ์ ๋ชจ๋๊ฐ ์ค์ค๋ก ํด๊ฒฐํด์ผ ํ๋ค"๊ณ ๋งํ๋ ๊ฒ์ฒ๋ผ ๋ค๋ฆฌ๊ธฐ ๋๋ฌธ์ ์ ๋ ์ฌ๊ธฐ์ ์ ๋ง ์ด๋ ค์์ ๊ฒช๊ณ ์์ต๋๋ค. ๊ทธ๊ฒ์ ์ต์
์ ์ฅ์ ์ค ํ๋์ธ ๊ฒ ๊ฐ์ต๋๋ค. ํ์คํ ๋๋ถ๋ถ์ ๊ณ ๊ฐ์ DoS ๋ฌธ์ ์ ๋ํด ์์ฒด '๋ง๋น ํด์'๋ฅผ ๋กค๋งํ๋ ๊ฒ์ ๋ํด ์๊ฐํ์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค. ๊ทธ๋ค์ ๋จ์ง ํ๋์ ์ต์ข
ํด์๋ก ํ๋ ํด์๋ฅผ ์ถ๊ฐ, xoring ๋๋ ์๋ชป ๊ฒฐํฉํ์ ๋ฟ์
๋๋ค.
95%์ ๊ฒฝ์ฐ์ ๊ด์ฌ์ด ์๋ค๋ฉด ์ผ๋ฐ์ ์ผ๋ก ์ข์ enogh ํด์๋ฅผ ๋ง๋ค์ด์ผ ํฉ๋๋ค. 5%์ ๊ฒฝ์ฐ๋ฅผ ์๊ฐํ๋ค๋ฉด ๊ทธ์ ๋ํ ํนํ๋ ์๋ฃจ์ ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
์ด๊ฒ์ ๋์๊ฒ ํฉ๋ฆฌ์ ์ผ๋ก ๋ณด์ ๋๋ค.
์ข์ต๋๋ค :) ๊ทธ๋ฐ ๋ค์ ๋ ธ์ถํ ์ ์์ต๋๊น?
```c#
๋ค์์คํ์ด์ค System.Numerics.Hashing
{
๋ด๋ถ ์ ์ ํด๋์ค HashHelpers
{
๊ณต๊ฐ ์ ์ ์ฝ๊ธฐ ์ ์ฉ int RandomSeed = ์๋ก์ด Random().Next(Int32.MinValue, Int32.MaxValue);
public static int Combine(int h1, int h2)
{
// RyuJIT optimizes this to use the ROL instruction
// Related GitHub pull request: dotnet/coreclr#1830
uint rol5 = ((uint)h1 << 5) | ((uint)h1 >> 27);
return ((int)rol5 + h1) ^ h2;
}
}
Roslyn could then generate:
```c#
return Hash.Combine(Hash.RandomSeed,
this.A?.GetHashCode() ?? 0,
this.B?.GetHashCode() ?? 0,
this.C?.GetHashCode() ?? 0);
์ด๊ฒ์ ๋๋ค์์ ๊ฒฝ์ฐ์ ์ค์ ๋ก "์ถฉ๋ถํ ์ข์" ์ด์ ์ด ์๋ ๋์์ ์ฌ๋๋ค์ ๋ฌด์์ ๊ฐ์ผ๋ก ์ด๊ธฐํํ๋ ์ข์ ๊ฒฝ๋ก๋ก ์๋ดํ์ฌ ๋ฌด์์๊ฐ ์๋ ํด์์ ์์กดํ์ง ์๋๋ก ํฉ๋๋ค.
๋ณด์/DoS ๋ฌธ์ ๊ฐ ์๋ ์ฌ๋์ ํด๋น ๋ชฉ์ ์ผ๋ก ๋ฌธ์ํ๋ ํน์ ์์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ชจ๋ ASP.NET ์ฑ์๋ ๋ณด์/DoS ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
์ข์ต๋๋ค :) ๊ทธ๋ฐ ๋ค์ ๋ ธ์ถํ ์ ์์ต๋๊น?
์ด๊ฒ์ ๋ด๊ฐ ํฉ๋ฆฌ์ ์ผ๋ก ๋งํ ๊ฒ๊ณผ ๋ค๋ฆ ๋๋ค.
https://github.com/aspnet/Common/blob/dev/shared/Microsoft.Extensions.HashCodeCombiner.Sources/HashCodeCombiner.cs ์ ๋ํด ์ด๋ป๊ฒ ์๊ฐ
@jkotas ๋ค์์ต๋๋ค :p
๋ฐ๋ผ์ ์ฌ๊ธฐ์ ๋ฌธ์ ๋ ๊ฐ๋ฐ์๊ฐ DoS ๊ณต๊ฒฉ์ ์ทจ์ฝํ ์์ ์ ๋ชจ๋ฅธ๋ค๋ ๊ฒ์ ๋๋ค. DoS ๊ณต๊ฒฉ์ ๋ํ ๋ฌธ์ ๊ฐ ์๋๊ธฐ ๋๋ฌธ์ Marvin32๋ฅผ ์ฌ์ฉํ๋๋ก ๋ฌธ์์ด์ ์ ํํ ๊ฒ์ ๋๋ค.
'95%์ ๊ฒฝ์ฐ๋ ์ค์ํ์ง ์๋ค'๋ ์์ผ๋ก ๋งํด์๋ ์ ๋๋ค. ์ฆ๋ช ํ ๋ฐฉ๋ฒ์ด ์๊ณ ์ฑ๋ฅ ๋๊ฐ๋ฅผ ์น๋ฅด๋๋ผ๋ ์ฃผ์๋ฅผ ๊ธฐ์ธ์ฌ์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๊ฒ์์ ๋ฒ์ด๋๋ ค๋ฉด ํด์ ์ฝ๋ ๊ตฌํ์ "์ด๊ฒ์ผ๋ก ์ถฉ๋ถํด ๋ณด์ ๋๋ค"๋ผ๊ณ ๊ฒฐ์ ํ๋ ๊ฒ์ด ์๋๋ผ Crypto Board ๊ฒํ ๊ฐ ํ์ํฉ๋๋ค.
๋ชจ๋ ASP.NET ์ฑ์๋ ๋ณด์/DoS ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
ํ์ธ. ๊ทธ๋์ ์ค๋๋ ์๋ฌด๋ ํด์์ฝ๋์ ๋ํ ๋์์ ๋ฐ์ง ๋ชปํ์ฌ ์ผ์ ์ ๋๋ก ํ์ง ๋ชปํ๋ ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ๊ณ ์์ต๋๊น? ๋ถ๋ช ํ ๊ทธ ์ธ๊ณ์ ์ํ๋ฅผ ๊ฐ๋ ๊ฒ์ด ์ฉ์ธ๋์์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์ค๋๋ ์ฌ๋๋ค์ด ์์ผ๋ก ๊ตด๋ฆฌ๋ ๊ฒ๋ณด๋ค ๋ ๋์ ์ฑ๋ฅ์ ๋ณด์ด๋ ํฉ๋ฆฌ์ ์ธ ํด์ฑ ์์คํ ์ ์ ๊ณตํ๋ฉด ์ด๋ค ํผํด๋ฅผ ์ ๊ฒ ๋ ๊น์?
์ ์ฆํ ๋ฐฉ๋ฒ์ด ์๊ณ ์ฑ๋ฅ ๋น์ฉ์ด ์๋๋ผ๋ ์ฃผ์๋ฅผ ๊ธฐ์ธ์ฌ์ผ ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋น์ ์ด ๋ฌด์ธ๊ฐ๋ฅผ ์ ๊ณตํ์ง ์์ผ๋ฉด ์ฌ๋๋ค์ ๊ณ์ํด์ ๋์ ์ผ์ ํ ๊ฒ์ ๋๋ค. ์๋ฒฝํ ๊ฒ์ด ์๊ธฐ ๋๋ฌธ์ "์ถฉ๋ถํ ์ข์ ๊ฒ"์ ๊ฑฐ๋ถํ๋ ๊ฒ์ ์ค๋๋ ์ฐ๋ฆฌ๊ฐ ๊ฐ์ง ์ด์ ํ ํ์์ ์๋ฏธํฉ๋๋ค.
๋ชจ๋ ASP.NET ์ฑ์๋ ๋ณด์/DoS ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
์ด๊ฒ์ ์ค๋ช ํ ์ ์์ต๋๊น? ๋ด๊ฐ ์๊ธฐ๋ก๋ ์์์ ์ ๋ ฅ์ ์๋ฝํ ๋ค์ ์ ๋ ฅ์ ํน์ํ๊ฒ ์กฐ์ํ ์ ์๋ ๊ฒฝ์ฐ ์ฑ๋ฅ์ด ๋จ์ด์ง๋ ์ผ๋ถ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ์ ์ฅํ๋ ๊ฒฝ์ฐ DoS ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์ข์, ๋๋ ๊ทธ๊ฒ์ด ์ฌ์ฉ์๋ก๋ถํฐ ์จ ์น ์๋๋ฆฌ์ค์์ ์ป๋ ๋ฌธ์์ด์ ๋ํ ์ฐ๋ ค๋ฅผ ์ดํดํฉ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด ์๋๋ฆฌ์ค์์ ์ฌ์ฉ๋์ง ์๋ ๋๋จธ์ง ์ ํ์๋ ์ด๋ป๊ฒ ์ ์ฉ๋ฉ๋๊น?
๋ค์ ์ ํ ์ธํธ๊ฐ ์์ต๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ฐ๋ฆฌ๋ ์ด๋ฌํ ๊ฒฝ์ฐ๊ฐ ์ค์ํ๋ค๊ณ ์๊ฐํ์ง๋ง ์ค์ ๋ก ์ฌ์ฉ์์๊ฒ '1' ๋๋ '2'๋ฅผ ์ฒ๋ฆฌํ๋ ์๋ฃจ์ ์ ์ ๊ณตํ ๋งํผ ์ค์ํ์ง ์์ต๋๋ค. ์ฐ๋ฆฌ๋ '2'์ ๋ํ ์๋ฃจ์ ์ด '1'์ ์ข์ง ์์ ๊ฒ์ด๋ผ๊ณ ๊ฑฑ์ ํ๊ธฐ ๋๋ฌธ์ ์ ์ด์ ์ ๊ณต์กฐ์ฐจ ํ์ง ์์ ๊ฒ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ๊ฐ '1'์ ๋ํ ํด๊ฒฐ์ฑ ์กฐ์ฐจ ์ ์ํ์ง ์๋๋ค๋ฉด ์ฐ๋ฆฌ๋ ๋ฏฟ์ ์ ์์ ์ ๋๋ก ์ด์ํ ์์น์ ์๋ ๊ฒ์ฒ๋ผ ๋๊ปด์ง๋๋ค. ์ฐ๋ฆฌ๋ DoSing๊ณผ ASP์ ๋ํด ๊ฑฑ์ ํ๊ณ ์์ง๋ง ์ค์ ๋ก ์ฌ๋๋ค์ ๋์ธ ๋งํผ ๊ฑฑ์ ํ์ง ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ๋ ๊ทธ ๋ฌธ์ ๋ก ์ฌ๋๋ค์ ๋์ง ์์ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ DoS๊ฐ ์๋ ๊ฒฝ์ฐ์๋ ๊ธฐ๊บผ์ด ๋์์ค ์๊ฐ๋ ์์ต๋๋ค.
--
์ด ๋ ๊ฐ์ง ๊ฒฝ์ฐ๊ฐ ์ค์ํ๋ค๋ฉด(์ ๋ ๊ธฐ๊บผ์ด ์๋ฝํ ์ ์์ต๋๋ค) ๋ ๊ฐ์ API๋ฅผ ์ ๊ณตํ์ง ์๋ ์ด์ ๋ ๋ฌด์์ ๋๊น? ๋ฌธ์ํํ์ญ์์ค. ๋ฌด์์ ์ํ ๊ฒ์ธ์ง ๋ช ํํ ํ์ญ์์ค. ์ฌ๋๋ค์ด ์ฌ๋ฐ๋ฅด๊ฒ ์ฌ์ฉํ๋ฉด ์ข์ต๋๋ค . ์ฌ๋๋ค์ด ๊ทธ๊ฒ์ ์ ๋๋ก ์ฌ์ฉํ์ง ์๋๋ค๋ฉด ๊ทธ๊ฒ์ ์ฌ์ ํ โโ๊ด์ฐฎ์ต๋๋ค. ๊ฒฐ๊ตญ, ๊ทธ๋ค์ ์ด์จ๋ ์ค๋๋ ์ ๋๋ก ์ผ์ ํ์ง ์์ ๊ฐ๋ฅ์ฑ์ด ๋์ผ๋ฏ๋ก ์ด๋ป๊ฒ ์ํฉ์ด ๋ ๋๋น ์ง ์ ์์ต๋๊น?
๋น์ ์ ๋ฌด์์ ์๊ฐํฉ๋๊น
๋๋ ์ด๋ค ์ ์ผ๋ก๋ ์๊ฒฌ์ด ์์ต๋๋ค. ๊ณ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ API๋ก ํ์ฉ ๊ฐ๋ฅํ ์ฑ๋ฅ๊ณผ ๋ช ํํ ์ฝ๋๊ฐ ํฌํจ๋ ๊ฐ๋จํ API๋ฅผ ์ ๊ณตํ๋ API๋ผ๋ฉด ๊ด์ฐฎ์ต๋๋ค.
์ ๋ ฌ๋ ๋ฐฉ์์ผ๋ก ํ๋/์์ฑ ์งํฉ์ ๊ฒฐํฉํ๋ ค๋ ๊ฒฝ์ฐ์ 99%๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฐ๋จํ ์ ์ ํ์์ด ์์ผ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค. ์ด ์ ํ์ ๊ทธ๋ฐ ๊ฒ์ ์๋นํ ๊ฐ๋จํ๊ฒ ์ถ๊ฐํ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค.
์ฌํํ ์คํํฑ ํํ๊ฐ ์์ผ๋ฉด ์ข์ ๊ฒ ๊ฐ์์
๋์ํ๋ค.
์ ๋ ฌ๋ ๋ฐฉ์์ผ๋ก ํ๋/์์ฑ ์งํฉ์ ๊ฒฐํฉํ๋ ค๋ ๊ฒฝ์ฐ์ 99%๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฐ๋จํ ์ ์ ํ์์ด ์์ผ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค. ์ด ์ ํ์ ๊ทธ๋ฐ ๊ฒ์ ์๋นํ ๊ฐ๋จํ๊ฒ ์ถ๊ฐํ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค.
๋์ํ๋ค.
์ผ์ข
์ API๊ฐ ๊ตฌํ๋๋ ๊ฒ์ ์ ๋ง๋ก ๋ณด๊ณ ์ถ๊ธฐ ๋๋ฌธ์ ์ด ๋ฌธ์ ์ ์ค๊ฐ์์ ๋ ๋ถ์ ๋ชจ๋ ๋ง๋๊ณ ์ถ์ต๋๋ค. @jkotas ๋๋ ๋น์ ์ด ๋ถ๋ณ์ ์ธ์คํด์ค ๊ธฐ๋ฐ API๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๋ฐ๋ h.Combine(a).Combine(b)
(๋ถ๋ณ ๋ฒ์ )์ h.Combine(a); h.Combine(b);
(๋ณ๊ฒฝ ๊ฐ๋ฅ)๋ณด๋ค ์งง์ต๋๋ค. ๋ฒ์ )).
์ฆ, ๋ค์์ผ๋ก ๋์๊ฐ ์ํฅ์ด ์์ต๋๋ค.
public static class HashCode
{
public static int Combine<T>(T value1, Tvalue2);
public static int Combine<T>(T value1, Tvalue2, IEqualityComparer<T> comparer);
public static int Combine<T>(T value1, Tvalue2, T value3);
public static int Combine<T>(T value1, Tvalue2, T value3, IEqualityComparer<T> comparer);
public static int Combine<T>(T value1, Tvalue2, T value3, T value4);
public static int Combine<T>(T value1, Tvalue2, T value3, T value4, IEqualityComparer<T> comparer);
// ... All the way until value8
}
์ด๊ฒ์ด ํฉ๋ฆฌ์ ์ผ๋ก ๋ณด์ ๋๊น?
์ง๊ธ์ ๋ด ๊ฒ์๋ฌผ์ ํธ์งํ ์ ์์ง๋ง ๋ชจ๋ ๋ฉ์๋๊ฐ T๋ฅผ ์๋ฝํ ์ ์๋ค๋ ๊ฒ์ ๊นจ๋ฌ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ๋ชจ๋ int๋ฅผ ์๋ฝํ๊ณ ์ฌ์ฉ์๊ฐ GetHashCode๋ฅผ ํธ์ถํ๋๋ก ํ๋ 8๊ฐ์ ์ค๋ฒ๋ก๋๋ง ๊ฐ์ง ์ ์์ต๋๋ค.
์ด ๋ ๊ฐ์ง ๊ฒฝ์ฐ๊ฐ ์ค์ํ๋ค๋ฉด(์ ๋ ๊ธฐ๊บผ์ด ์๋ฝํ ์ ์์ต๋๋ค) ๋ ๊ฐ์ API๋ฅผ ์ ๊ณตํ์ง ์๋ ์ด์ ๋ ๋ฌด์์ ๋๊น? ๋ฌธ์ํํ์ญ์์ค. ๋ฌด์์ ์ํ ๊ฒ์ธ์ง ๋ช ํํ ํ์ญ์์ค. ์ฌ๋๋ค์ด ์ฌ๋ฐ๋ฅด๊ฒ ์ฌ์ฉํ๋ฉด ์ข์ต๋๋ค. ์ฌ๋๋ค์ด ๊ทธ๊ฒ์ ์ ๋๋ก ์ฌ์ฉํ์ง ์๋๋ค๋ฉด ๊ทธ๊ฒ์ ์ฌ์ ํ โโ๊ด์ฐฎ์ต๋๋ค. ๊ฒฐ๊ตญ, ๊ทธ๋ค์ ์ด์จ๋ ์ค๋ ์ผ์ ์ ๋๋ก ํ์ง ์์ ๊ฐ๋ฅ์ฑ์ด ๋์ผ๋ ์ด๋ป๊ฒ ์ํฉ์ด ๋ ๋๋น ์ง๊น์?
์ฌ๋๋ค์ ๊ทธ๊ณณ์ ์์ ๋ ๋ฌผ๊ฑด์ ์ ๋๋ก ์ฌ์ฉํ์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ฐ๋จํ ์๋ฅผ ๋ค์ด ๋ณด๊ฒ ์ต๋๋ค. XSS. ์ฒ์๋ถํฐ ์น ์์์๋ HTML ์ธ์ฝ๋ฉ ์ถ๋ ฅ ๊ธฐ๋ฅ์ด ์์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ฐ๋ฐ์๋ ์ํ์ ์์ง ๋ชปํ๊ณ ์ฌ๋ฐ๋ฅด๊ฒ ์ํํ๋ ๋ฐฉ๋ฒ์ ๋ชฐ๋๊ณ ๋๋ฌด ๋ฆ์์ ๋ ์ฑ์ด ๊ฒ์๋์์ผ๋ฉฐ ์์ค, ์ด์ ์ธ์ฆ ์ฟ ํค๊ฐ ํด์ ๋์์ต๋๋ค.
์ฌ๋๋ค์๊ฒ ๋ณด์ ์ ํ๊ถ์ ์ฃผ๋ ๊ฒ์ ๊ทธ๋ค์ด
์ด๋ฌํ ๊ฐ์ ์ ์ผ๋ฐ์ ์ผ๋ก ๋๋ค์์ ๊ฐ๋ฐ์์๊ฒ ์ ์ฉ๋์ง ์์ผ๋ฉฐ ๋๋ฌด ๋ฆ์์ ๋๋ง ๋ฌธ์ ๋ฅผ ์ฐพ์ต๋๋ค. ๊ฐ๋ฐ์๋ ๋ณด์ ํ์์ ๊ฐ์ง ์๊ณ ๋ฐฑ์๋ฅผ ์ฝ์ง ์์ผ๋ฉฐ ์๋ฃจ์ ์ ์ดํดํ์ง ๋ชปํฉ๋๋ค. ๊ทธ๋์ ASP.NET HashDoS ์๋๋ฆฌ์ค์์ ์ฐ๋ฆฌ๋ ๊ทธ๋ค์ ์ํด ์ ํํ๊ณ , ๊ธฐ๋ณธ์ ์ผ๋ก ๋ณดํธํ์ต๋๋ค. ๊ทธ๊ฒ์ด ์ณ์ ์ผ์ด์๊ณ ๊ฐ์ฅ ํฐ ์ํฅ์ ๋ฏธ์ณค๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ๋ฌธ์์ด์๋ง ์ ์ฉํ๊ณ , ์ด๋ ์ฌ์ฉ์ ์ ๋ ฅ์ผ๋ก ์ปค์คํ ํด๋์ค๋ฅผ ์์ฑํ๋ ์ฌ๋๋ค์ ๋์ ์์น์ ๋จ๊ฒจ๋์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ณ์ ์ผ์ ํด์ผ ํ๊ณ , ์ง๊ธ ๊ทธ ๊ณ ๊ฐ์ ๋ณดํธํ๋๋ก ๋๊ณ , ์คํจ๊ฐ ์๋ ์ฑ๊ณต์ ๊ตฌ๋ฉ์ด๋ฅผ ๊ฐ์ง๊ณ ๊ธฐ๋ณธ์ผ๋ก ์ค์ ํด์ผ ํฉ๋๋ค. ๋ณด์์ ์ํ API ์ค๊ณ๋ ๋๋๋ก ์ ํ์ด ์๋๋ผ ์ฌ์ฉ์๊ฐ ์๋ ๋ชจ๋ฅด๋ ์ฌ์ฉ์๋ฅผ ๋๋ ๊ฒ์ ๋๋ค.
์ฌ์ฉ์๋ ํญ์ ๋ณด์์ ์ค์ ์ ๋์ง ์์ ํด์๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ๊ทธ๋์ ๋ ๊ฐ์ง ์ต์ ์ด ์ฃผ์ด์ก์ ๋
๊ทธ๋ ๋ค๋ฉด ๋ ๋ฒ์งธ๊ฐ ๋ ๋์ ๊ฒ์ ๋๋ค. ์ ์๋ ๊ฒ์ ์ ์ฒด ์ํธํ ํด์์ ์ฑ๋ฅ์ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค. ๊ทธ๋์ ๊ทธ๊ฒ์ ์ข์ ํํ์ ๋ง๋๋๊ฐ?
์ด ์ค๋ ๋์์ ์คํ ์ค์ธ ์ง๋ฌธ ์ค ํ๋๋ ์ด๋ค ์๊ณ ๋ฆฌ์ฆ์ด ๋ชจ๋ ์ฌ๋์๊ฒ ์๋ฒฝํ๊ฐ ํ๋ ๊ฒ์ ๋๋ค. ์๋ฒฝํ ์๊ณ ๋ฆฌ์ฆ์ ์๋ค๊ณ ๋งํ๋ ๊ฒ์ด ์์ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ฌ๋ @CyrusNajmabadi ๊ฐ ๋ณด์ฌ์ค ๊ฒ๊ณผ ๊ฐ์ ์ฝ๋๋ณด๋ค ๋ ๋์ ๊ฒ์ ์ ๊ณตํ๋ ๊ฒ์ ๋ง์ ์๋ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ด ์ฝ๋๋ ์ผ๋ฐ์ ์ธ .NET ์ ๋ ฅ ๋ฐ ๊ธฐํ ์ผ๋ฐ์ ์ธ ํด์ ๋ฒ๊ทธ(์: ์ ๋ ฅ ๋ฐ์ดํฐ ์์ค ๋๋ ์ฝ๊ฒ ์ฌ์ค์ ๊ฐ๋ฅ).
"์ต์์ ์๊ณ ๋ฆฌ์ฆ" ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ช ๊ฐ์ง ์ต์ ์ ์ ์ํ๊ณ ์ถ์ต๋๋ค.
Marvin32.Create();
์์ฑํ๋ฉด ๊ณ ๊ธ ์ฌ์ฉ์์๊ฒ ๋ฌด์์ ํ๊ธฐ๋ก ๊ฒฐ์ ํ๋์ง ์๋ฆด ์ ์์ผ๋ฉฐ ์ํ๋ ๊ฒฝ์ฐ ์ ํ๊ตฐ์ ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ์ฝ๊ฒ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.CC @bartonjs , @terrajobst
@morganbr ํ๋์ ์๋ฒฝํ ์๊ณ ๋ฆฌ์ฆ์ ์์ง๋ง ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ๊ฝค ์ ์๋ํ๋ ์ผ๋ถ ์๊ณ ๋ฆฌ์ฆ์ ๊ฐ๋จํ๊ณ ์ดํดํ๊ธฐ ์ฌ์ด API๋ฅผ ์ฌ์ฉํ์ฌ ๋
ธ์ถํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ ์ฉํ ์์
์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๊ณ ๊ธ ์ฉ๋์ ๊ฒฝ์ฐ ๊ทธ ์ธ์๋ ์๊ณ ๋ฆฌ์ฆ ๋ชจ์์ ๊ฐ๋ ๊ฒ์ด ์ข์ต๋๋ค. ํ์ง๋ง ์ด๊ฒ์ด ์ ์ผํ ์ ํ์ ์๋์ด์ Dictionary
์ ๋ด ๋ฌผ๊ฑด์ ๋ฃ์ ์ ์๋๋ก Marvin์ด ๋๊ตฐ์ง ์ ํ์๊ฐ ์์ต๋๋ค.
๋ด ๋ฌผ๊ฑด์ ์ฌ์ ์ ๋ฃ์ ์ ์๋๋ก Marvin์ด ๋๊ตฌ์ธ์ง ๋ฐฐ์ธ ํ์๊ฐ ์์ต๋๋ค.
๋๋ ๋น์ ์ด ๊ทธ๊ฒ์ ๋ฃ๋ ๋ฐฉ์์ ์ข์ํฉ๋๋ค. ๋๋ ๋ํ ๋น์ ์ด ์ฌ์ ์์ฒด๋ฅผ ์ธ๊ธํ๋ ๊ฒ์ ์ข์ํฉ๋๋ค. IDictionary๋ ๋ชจ๋ ์ข ๋ฅ์ ๋ค๋ฅธ ํ์ง์ ๊ฐ์ง ์๋ง์ ๋ค๋ฅธ impls๋ฅผ ๊ฐ์ง ์ ์๋ ๊ฒ์ ๋๋ค(๋ง์ ํ๋ซํผ์ ์ปฌ๋ ์ API ์ฐธ์กฐ). ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๋ ์ฌ์ ํ ๋ชจ๋ ๋ฒ์ฃผ์์ ํ์ํ์ง๋ ์๋๋ผ๋ ์ ๋ฐ์ ์ผ๋ก ๊ด์ฐฎ์ ์์ ์ ์ํํ๋ ๊ธฐ๋ณธ '์ฌ์ '์ ์ ๊ณตํฉ๋๋ค.
๋๋ ์ฌ๋๋ค์ ํค์ด ํด์ฑ ๋์๊ด์์ ๋ฌด์์ ์ฐพ๊ณ ๊ทธ์๋ฅผ ์๊ฐํ๋ค. ๋ชจ๋ ๋ชฉ์ ์ ์๋ฒฝํ์ง๋ ์๋๋ผ๋ ์์ ์ ์๋ฃํ๋ ๊ฒ.
@morganbr ๋ด ์๊ฐ์ ์ฌ๋๋ค์ ํ์ฌ ํ๊ณ ์๋ ๊ฒ๋ณด๋ค ๋ ๋์ GetHashCode๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค(์ผ๋ฐ์ ์ผ๋ก ์น์์ ๋ณต์ฌํ ์ํ ์ฐ์ฐ์ ์ผ๋ถ ์ก๊ธฐ ์กฐํฉ). ๊ทธ ๋ฃฌ์ ๋ํ ๊ธฐ๋ณธ์ ์ธ ์์๋ง ์ ๊ณตํ ์ ์๋ค๋ฉด ์ฌ๋๋ค์ ํ๋ณตํ ๊ฒ์ ๋๋ค. ๊ทธ๋ฐ ๋ค์ ํน์ ํด์ฑ ๊ธฐ๋ฅ์ด ๋งค์ฐ ํ์ํ ๊ฒฝ์ฐ ๊ณ ๊ธ ์ฌ์ฉ์๋ฅผ ์ํ ๋นํ์ธ๋ API๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ค์ ๋งํด, ์ค๋๋ ํด์์ฝ๋๋ฅผ ์์ฑํ๋ ์ฌ๋๋ค์ Spooky vs Marvin vs Murmur๋ฅผ ์ํ๋ ์ด์ ๋ฅผ ์์ง ๋ชปํ๊ฑฐ๋ ์ ๊ฒฝ ์ฐ์ง ์์ ๊ฒ์ ๋๋ค. ํน์ ํด์ ์ฝ๋ ์ค ํ๋๊ฐ ํน๋ณํ ํ์ํ ์ฌ๋๋ง ๊ฒ์ํ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ๋ง์ ์ฌ๋๋ค์ "์ฌ๊ธฐ ๋ด ๊ฐ์ฒด์ ์ํ๊ฐ ์์ต๋๋ค. ์ฌ์ ๊ณผ ํจ๊ป ์ฌ์ฉํ ์ ์๋ ๋น ๋ฅด๊ณ ์ ๋ถ์ฐ๋ ํด์๋ฅผ ์์ฑํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ธ์. ์ ๋ขฐํ ์ ์๋ ์ ๋ ฅ์ ๋ฐ์ ํด์ํ๊ณ ์ ์ฅํฉ๋๋ค."
@CyrusNajmabadi ๋ฌธ์ ๋ ํธํ์ฑ์ ๋ํ ํ์ฌ ๊ฐ๋ ์ ๋ฏธ๋๋ก ํ์ฅํ๋ฉด ์ด ์ ํ์ด
Once๋ ์์ ์ ์ธ ๋ฌด์์ ๋ฐฉ์์ผ๋ก ์์ํ๋ฉด ์คํ์์ ์คํ์ผ๋ก ๊ฐ์ ์์กดํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ตฌํ์ ๋ณ๊ฒฝํ๊ธฐ ์ฌ์์ง๋ค๊ณ ์ฃผ์ฅํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ช ๋
ํ ์ฐ๋ฆฌ๋ ํด์ ๋ฒํท์ ๊ท ํ์ ์ ์งํ๋ฉด์ ์ผ๋ฐ์ ์ผ๋ก ๋ ๋์ ์ฑ๋ฅ์ ์ ๊ณตํ์ง๋ง List\ Morgan์ ์ ์์ ๋ฐ๋ฅด๋ฉด ์ค๋ ์์ฑํ๋ ์ฝ๋๋ ์ฌ์ค์ ์์ํ ๋์ผํ ์ฑ๋ฅ ํน์ฑ์ ๊ฐ์ง ๊ฒ์
๋๋ค. ๋ ๋์์ง ์ ์์๋ ์์ฉ ํ๋ก๊ทธ๋จ์ ๊ฒฝ์ฐ ์ด๊ฒ์ ๋ถํํ ์ผ์
๋๋ค. ๋ ๋๋น ์ก์ ์์ฉ ํ๋ก๊ทธ๋จ์ ๊ฒฝ์ฐ ์ด๊ฒ์ ํ์์ ์
๋๋ค. ๊ทธ๋ฌ๋ ์ ์๊ณ ๋ฆฌ์ฆ์ ์ฐพ์ผ๋ฉด ์ฒดํฌ์ธํ๊ณ Roslyn์ ๋ณ๊ฒฝํ๊ณ (ReSharper/etc๋ก ๋ณ๊ฒฝ ์ ์) SomeThingThatWasConsideredAwesomeIn2018 ๋์ NewAwesomeThing2019๋ก ์์ฑ์ ์์ํฉ๋๋ค. ์ด์ ๊ฐ์ ์ํผ ๋ธ๋๋ฐ์ค๋ ๋จ ํ ๋ฒ๋ง ๊ฐ๋ฅํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ฐ๋ฆฌ๋ ์์ํ ๋ถ์ด ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ๋๊ตฐ๊ฐ๊ฐ ๋ ๋์ ํ๊ท ์ฑ๋ฅ์ ๊ฐ์ง ๋ค์ ๊ฒ์ ์์ฑํฉ๋๋ค. ๊ทธ๋์ ๋น์ ์ด ๊ทธ๋ค ์ฌ์ด์์ ์ ํํด์ผ ํ๋ ์ด์ ๋ฅผ ๋ชจ๋ฅด๋ ๋ ๊ฐ์ ๋ธ๋๋ฐ์ค ๊ตฌํ์ด ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋์... ๊ทธ๋ฆฌ๊ณ ๋์... . ๋ฐ๋ผ์ Roslyn/ReSharper/etc๊ฐ Marvin32, Murmur, FastHash ๋๋ IntPtr.Size ๊ธฐ๋ฐ ์กฐํฉ/์กฐ๊ฑด์ ์ฌ์ฉํ์ฌ GetHashCode๋ฅผ ์๋์ผ๋ก ์์ฑํ ์ด์ ๋ฅผ ๋ชจ๋ฅผ ์๋ ์์ต๋๋ค. ํ์ง๋ง ๋น์ ์ ๊ทธ๊ฒ์ ๋ค์ฌ๋ค๋ณผ ์ ์๋ ํ์ด ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์๋ก์ด ์ ๋ณด๊ฐ ๊ณต๊ฐ๋๋ฉด ๋์ค์ ์ ํ์ ๋ณ๊ฒฝํ ์ ์๋ ๊ถํ์ด ์์ต๋๋ค. ํ์ง๋ง ์ฐ๋ฆฌ๋ ๋ํ ๊ทธ๋๋ก ์ ์งํ ์ ์๋ ๊ถํ๋ ์ฃผ์์ต๋๋ค. (๋ง์ฝ ์ฐ๋ฆฌ๊ฐ ์ด๊ฒ์ ์์ฑํ๋ค๋ฉด ์ฌํ ์ผ์ด ๋ ๊ฒ์
๋๋ค. ๊ทธ๋ฆฌ๊ณ 3๋
์์ Roslyn/ReSharper/etc๋ ๋ช
์์ ์ผ๋ก ๊ทธ๊ฒ์ ํธ์ถํ๋ ๊ฒ์ ํผํ๊ฒ ๋ ๊ฒ์
๋๋ค. ์๋ํ๋ฉด ์๋ก์ด ์๊ณ ๋ฆฌ์ฆ์ด ํจ์ฌ ๋ ๋ซ๊ธฐ ๋๋ฌธ์
๋๋ค... ์ผ๋ฐ์ ์ผ๋ก).
@bartonjs .Net์ด ๋ธ๋๋ฐ์ค ์๊ณ ๋ฆฌ์ฆ์ด๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ๊ณตํ๋ ๋ชจ๋ ๊ณณ์์ ํด์ฑ์ด ๋ค๋ฅธ ์ ์ ๋ฌด์์
๋๊น? ์๋ฅผ ๋ค์ด ์ ๋ ฌ(introsort), Dictionary
(๋ฐฐ์ด ๊ธฐ๋ฐ ๊ฐ๋ณ ์ฐ๊ฒฐ), StringBuilder
(8k ์ฒญํฌ์ ์ฐ๊ฒฐ ๋ชฉ๋ก), ๋๋ถ๋ถ์ LINQ.
์ค๋์ ์ด์ ๋ํด ์์ธํ ์ดํด๋ณด์์ต๋๋ค. ์ด ๋ฌธ์ ์ ๋ํด ์๋ค๋ก ์ง์ฐ๋ ์ ์ฌ๊ณผ๋๋ฆฝ๋๋ค.
```C#
// ์ฝ์ด ์ด์
๋ธ๋ฆฌ์ ์์ ๊ฒ์
๋๋ค.
// .NET ํ๋ ์์ํฌ: mscorlib
// .NET ์ฝ์ด : System.Runtime / System.Private.CoreLib
๋ค์์คํ์ด์ค ์์คํ
{
๊ณต๊ฐ ๊ตฌ์กฐ์ฒด ํด์ ์ฝ๋
{
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public void Add<T>(T value);
public void Add<T>(T value, IEqualityComparer<T> comparer);
public void Add<T>(T[] value);
public void Add<T>(T[] value, int index, int length);
public void Add(byte[] value);
public void Add(byte[] value, int index, int length);
public void Add(string value);
public void Add(string value, StringComparison comparisonType);
public int ToHashCode();
}
}
Notes:
* We decided to not override `GetHashCode()` to produce the hash code as this would be weird, both naming-wise as well as from a behavioral standpoint (`GetHashCode()` should return the object's hash code, not the one being computed).
* We decided to use `Add` for the builder patter and `Combine` for the static construction
* We decided to use not provide a static initialization method. Instead, `Add` will do this on first use.
* The struct is mutable, which is unfortunate but we feel the best compromise between making `GetHashCode()` very cheap & not cause any allocations while allowing the structure to be bigger than 32-bit so that the hash code algorithm can use more bits during accumulation.
* `Combine` will just call `<value>.GetHashCode()`, so it has the behavior of the value's type `GetHashCode()` implementation
- For strings that means different casing will produce different hash codes
- For arrays, that means the hash code doesn't look at the contents but uses reference semantics for the hash code
- If that behavior is undesired, the developer needs to use the builder-style approach
### Usage
The simple case is when someone just wants to produce a good hash code for a given type, like so:
```C#
public class Customer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public override int GetHashCode() => HashCode.Combine(Id, FirstName, LastName);
}
๋ ๋ณต์กํ ๊ฒฝ์ฐ๋ ๊ฐ๋ฐ์๊ฐ ํด์๊ฐ ๊ณ์ฐ๋๋ ๋ฐฉ์์ ์กฐ์ ํด์ผ ํ๋ ๊ฒฝ์ฐ์ ๋๋ค. ์์ด๋์ด๋ ํธ์ถ ์ฌ์ดํธ๊ฐ ๋ค์๊ณผ ๊ฐ์ด ๊ฐ์ฒด/๊ฐ์ด ์๋ ์ํ๋ ํด์๋ฅผ ์ ๋ฌํ๋ค๋ ๊ฒ์ ๋๋ค.
```C#
๊ณต๊ฐ ๋ถ๋ถ ํด๋์ค ๊ณ ๊ฐ
{
๊ณต๊ฐ ์ฌ์ ์ int GetHashCode() =>
HashCode.Combine(
ID,
StringComparer.OrdinalIgnoreCase.GetHashCode(์ด๋ฆ),
StringComparer.OrdinalIgnoreCase.GetHashCode(์ฑ),
);
}
And lastly, if the developer needs more flexibility, such as producing a hash code for more than eight values, we also provide a builder-style approach:
```C#
public partial class Customer
{
public override int GetHashCode()
{
var hashCode = new HashCode();
hashCode.Add(Id);
hashCode.Add(FirstName, StringComparison.OrdinalIgnoreCase);
hashCode.Add(LastName, StringComparison.OrdinalIgnoreCase);
return hashCode.ToHashCode();
}
}
์ด ๋ฌธ์ ๋ ๊ณ์ ํด๊ฒฐ๋ ๊ฒ์ ๋๋ค. API๋ฅผ ๊ตฌํํ๋ ค๋ฉด ์ฌ์ฉํ ์๊ณ ๋ฆฌ์ฆ์ ๊ฒฐ์ ํด์ผ ํฉ๋๋ค.
@morganbr ์ด ์ข์ ํ๋ณด์๋ฅผ ์ ์ํฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๋งํด์, ์ฐ๋ฆฌ๋ ํด์ฑ ์๊ณ ๋ฆฌ์ฆ์ ์ฒ์๋ถํฐ ์์ฑํ๊ณ ์ถ์ง ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์์ฑ์ด ์ ์๋ ค์ง ์ ์๋ ค์ง ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๊ธฐ๋ฅผ ์ํฉ๋๋ค.
๊ทธ๋ฌ๋ ์ผ๋ฐ์ ์ธ .NET ์ํฌ๋ก๋์ ๋ํ ๊ตฌํ์ ์ธก์ ํ๊ณ ์ด๋ค ์๊ณ ๋ฆฌ์ฆ์ด ์ข์ ๊ฒฐ๊ณผ(์ฒ๋ฆฌ๋ ๋ฐ ๋ฐฐํฌ)๋ฅผ ์์ฑํ๋์ง ํ์ธํด์ผ ํฉ๋๋ค. ๋๋ต์ CPU ์ํคํ ์ฒ์ ๋ฐ๋ผ ๋ค๋ฅผ ์ ์์ผ๋ฏ๋ก ์ธก์ ํ ๋ ์ด๋ฅผ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
@jamesqo , ์ฌ์ ํ ์ด ๋ถ์ผ์์ ์ผํ๋ ๋ฐ ๊ด์ฌ์ด ์์ต๋๊น? ์ด ๊ฒฝ์ฐ ๊ทธ์ ๋ฐ๋ผ ์ ์์ ์ ๋ฐ์ดํธํ์ญ์์ค.
@terrajobst , ์ฐ๋ฆฌ๋ public static int Combine<T1>(T1 value);
๋ ์ํ ์ ์์ต๋๋ค. ๋๋ ๊ทธ๊ฒ์ด ์กฐ๊ธ ์ฌ๋ฏธ์์ด ๋ณด์ธ๋ค๋ ๊ฒ์ ์๊ณ ์์ง๋ง ์ ํ๋ ์
๋ ฅ ํด์ ๊ณต๊ฐ์ ๊ฐ์ง ๋ฌด์ธ๊ฐ๋ก๋ถํฐ ๋นํธ๋ฅผ ํ์ฐ์ํค๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ ๊ฒ์
๋๋ค. ์๋ฅผ ๋ค์ด, ๋ง์ ์ด๊ฑฐํ์๋ ์ฝ๋์ ๋งจ ์๋ ๋ช ๋นํธ๋ง ์ฌ์ฉํ๋ ๋ช ๊ฐ์ง ๊ฐ๋ฅํ ํด์๋ง ์์ต๋๋ค. ์ผ๋ถ ์ปฌ๋ ์
์ ํด์๊ฐ ๋ ๋์ ๊ณต๊ฐ์ ํผ์ ธ ์๋ค๋ ๊ฐ์ ํ์ ๊ตฌ์ถ๋๋ฏ๋ก ๋นํธ๋ฅผ ๋ถ์ฐํ๋ฉด ์ปฌ๋ ์
์ด ๋ณด๋ค ํจ์จ์ ์ผ๋ก ์๋ํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
public void Add(string value, StrinComparison comparison);
Nit: StringComparison
๋งค๊ฐ๋ณ์๋ StringComparison
๊ฐ ๋งค๊ฐ๋ณ์๋ก ์ฌ์ฉ๋๋ ๋ค๋ฅธ ๋ชจ๋ ๊ณณ์์ ์ฌ์ฉ๋๋ ์ด๋ฆ๊ณผ ์ผ์นํ๋๋ก comparisonType
๋ก ์ด๋ฆ์ ์ง์ ํด์ผ ํฉ๋๋ค.
์๊ณ ๋ฆฌ์ฆ์ ์ ํํ๋ ๋ฐ ๋์์ด ๋๋ ๊ธฐ์ค์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ฐ๋ฆฌ๊ฐ ์ ๋ง๋ก ๋ณด๊ณ ์ถ์ ๊ฒ์ C#์ผ๋ก ์์ฑ๋ ํ๋ณด์์ ์ฑ๋ฅ ์์น์ด๋ฏ๋ก ๊ทธ๋ค์ ํน์ฑ์ด .NET์์ ์ ์ง๋ ๊ฒ์ด๋ผ๊ณ ํฉ๋ฆฌ์ ์ผ๋ก ํ์ ํ ์ ์์ต๋๋ค. ๋น์ ์ด ํ๋ณด๋ฅผ ์์ฑํ๊ณ ์ฐ๋ฆฌ๊ฐ ์ด๊ฒ์ ์ํด ๊ทธ๊ฒ์ ์ ํํ์ง ์๋๋ค๋ฉด, ๋ด๊ฐ ์ค์ ๋ก ๋น์ํธํ ํด์ API์ ๋ํ API ์ ์์ ํจ๊ป ์ป์ ๋๋ง๋ค ์ฌ์ ํ ์ ์ฉํ ์์ ์ด ๋ ๊ฒ์ ๋๋ค.
๋ค์์ ํ๊ฐํ ๊ฐ์น๊ฐ ์๋ค๊ณ ์๊ฐ๋๋ ๋ช ๊ฐ์ง ํ๋ณด์์ ๋๋ค(๊ทธ๋ฌ๋ ๋ค๋ฅธ ์ฌ๋์ ์์ ๋กญ๊ฒ ์ ์ํ ์ ์์).
Add
๋ฉ์๋๋ ref HashCode
์ ๋ฐํ ์ ํ์ ๊ฐ์ง ์ ์๊ณ ์ ์ฐฝํ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ref this
๋ฐํํฉ๋๋ค.
readonly ref
๋ฐํ์ด ์ด๋ฅผ ํ์ฉํฉ๋๊น? /cc @jaredpar @VSadov
๊ฒฝ๊ณ : ๋๊ตฐ๊ฐ ์ธํฐ๋ท ์ด๋๊ฐ์ ์๋ ๊ธฐ์กด ์ฝ๋ ๊ธฐ๋ฐ์์ ํด์ ๊ตฌํ์ ์ ํํ๋ ๊ฒฝ์ฐ ์์ค์ ๋ํ ๋งํฌ๋ฅผ ์ ์งํ๊ณ ๋ผ์ด์ ์ค๋ฅผ ํ์ธํ์ญ์์ค(์ ํฌ๋ ๊ทธ๋ ๊ฒ ํด์ผ ํฉ๋๋ค).
๋ผ์ด์ผ์ค๊ฐ ํธํ๋์ง ์์ผ๋ฉด ์๊ณ ๋ฆฌ์ฆ์ ์ฒ์๋ถํฐ ์์ฑํด์ผ ํ ์๋ ์์ต๋๋ค.
Add ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ IMO๋ ๋งค์ฐ ๋๋ฌธ ์ผ์ ๋๋ค. ๋งค์ฐ ๊ณ ๊ธ ์๋๋ฆฌ์ค๋ฅผ ์ํ ๊ฒ์ด๋ฉฐ '์ ์ฐฝํ' ๋ฅ๋ ฅ์ด ํ์ํ์ง ์์ต๋๋ค.
๋ชจ๋ ์ฌ์ฉ์ ์ฝ๋ ์ฌ๋ก์ 99%์ ๋ํ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก์ ๊ฒฝ์ฐ => HashCode.Combine(...)
์ฌ์ฉํ ์ ์์ด์ผ ํ๊ณ ๊ด์ฐฎ์ต๋๋ค.
@morganbr
public static int Combine<T1>(T1 value);
๋ ์ํ ์ ์์ต๋๋ค. ๋๋ ๊ทธ๊ฒ์ด ์ฝ๊ฐ ์ฌ๋ฏธ์์ด ๋ณด์ธ๋ค๋ ๊ฒ์ ์๊ณ ์์ง๋ง ์ ํ๋ ์ ๋ ฅ ํด์ ๊ณต๊ฐ์ ๊ฐ์ง ๋ฌด์ธ๊ฐ์์ ๋นํธ๋ฅผ ํ์ฐ์ํค๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ ๊ฒ์ ๋๋ค
์ดํดํด. ๋๋ ๊ทธ๊ฒ์ ์ถ๊ฐํ๋ค.
@justinvp
Nit:
StringComparison
๋งค๊ฐ๋ณ์๋StringComparison
๊ฐ ๋งค๊ฐ๋ณ์๋ก ์ฌ์ฉ๋๋ ๋ค๋ฅธ ๋ชจ๋ ๊ณณ์์ ์ฌ์ฉ๋๋ ์ด๋ฆ๊ณผ ์ผ์นํ๋๋กcomparisonType
๋ก ์ด๋ฆ์ ์ง์ ํด์ผ ํฉ๋๋ค.
๊ฒฐ์ ๋.
@CyrusNajmabadi
IMO์์
Add
๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ ๊ฒ์ ๊ทนํ ๋๋ฌธ ์ผ์ ๋๋ค. ๋งค์ฐ ๊ณ ๊ธ ์๋๋ฆฌ์ค๋ฅผ ์ํ ๊ฒ์ด๋ฉฐ '์ ์ฐฝํ' ๋ฅ๋ ฅ์ด ํ์ํ์ง ์์ต๋๋ค.
๋์.
@benaadams - ์ฌ : ์ฌํ ๋ฐํ this
์์ Add
- ์๋, this
๊ทธ๊ฒ์ด๋ฅผ rvalue ๋๋ ์์ ๋ ์ ์๊ธฐ ๋๋ฌธ์ ๊ตฌ์กฐ์ฒด ๋ฐฉ๋ฒ์ ์ฌํ์ ์ํด ๋ฐํ ํ ์ ์์ต๋๋ค.
```C#
์ฐธ์กฐ var r = (์๋ก์ด T()).ReturnsRefThis();
// r์ ์ฌ๊ธฐ์์ ์ด๋ค ๋ณ์๋ฅผ ์ฐธ์กฐํฉ๋๋ค. ์ด๋ ๊ฒ? ๋ฒ์/์๋ช
์ด๋ ๋ฌด์์
๋๊น?
r = SomethingElse();
```
๋น๊ต ๋ชฉ์ ์ผ๋ก ์ ์ฉํ ๊ฒฝ์ฐ ๋ช ๋ ์ ์ Jenkins lookup3 ํด์ ํจ์( C ์์ค )๋ฅผ ์ฌ๊ธฐ ์์ C#์ผ๋ก ์ด์ํ์ต๋๋ค.
์ปฌ๋ ์ ์ ๋ํด ๊ถ๊ธํฉ๋๋ค.
@terrajobst
c# public void Add<T>(T[] value);
๋ฐฐ์ด์๋ ์ค๋ฒ๋ก๋๊ฐ ์์ง๋ง ์ผ๋ฐ ์ปฌ๋ ์
์๋ ์ค๋ฒ๋ก๋๊ฐ ์๋ ์ด์ (์: IEnumerable<T>
)๋ ๋ฌด์์
๋๊น?
๋ํ HashCode.Combine(array)
๋ฐ hashCode.Add((object)array)
ํ ๋ฐฉํฅ์ผ๋ก ์๋ํ๊ณ (์ฐธ์กฐ ํ๋ฑ ์ฌ์ฉ) hashCode.Add(array)
๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ์๋ํ๋ ๊ฒ์ด ํผ๋๋์ง ์์ต๋๊น? ๋ฐฐ์ด)?
@CyrusNajmabadi
๋ชจ๋ ์ฌ์ฉ์ ์ฝ๋ ์ฌ๋ก์ 99%์ ๋ํ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก์ ๊ฒฝ์ฐ
=> HashCode.Combine(...)
๋ง ์ฌ์ฉํ๋ฉด ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
๋ชฉํ๊ฐ ์ค์ ๋ก ์ฌ์ฉ ์ฌ๋ก์ 99%(์: 80%๊ฐ ์๋)์์ Combine
๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฒ์ด๋ผ๋ฉด Combine
๊ฐ ๊ฐ์ ๊ธฐ๋ฐ์ผ๋ก ํด์ฑ ์ปฌ๋ ์
์ ์ง์ํด์๋ ์ ๋ฉ๋๋ค. ์ปฌ๋ ์
์์? ์๋ง๋ ์ด๋ฅผ ์ํํ๋ ๋ณ๋์ ๋ฉ์๋๊ฐ ์์ด์ผ ํฉ๋๋ค( HashCode
์ ํ์ฅ ๋ฉ์๋ ๋๋ ์ ์ ๋ฉ์๋)?
์ถ๊ฐ๊ฐ ๊ฐ๋ ฅํ ์๋๋ฆฌ์ค์ธ ๊ฒฝ์ฐ ์ฌ์ฉ์๊ฐ Object.GetHashCode์ ์ปฌ๋ ์
์ ๊ฐ๋ณ ์์ ๊ฒฐํฉ ์ค์์ ์ ํํด์ผ ํ๋ค๊ณ ๊ฐ์ ํด์ผ ํฉ๋๊น? ๋์์ด ๋๋ค๋ฉด ๋ฐฐ์ด(๋ฐ ์ ์ฌ์ ์ธ IEnumerable) ๋ฒ์ ์ ์ด๋ฆ์ ๋ฐ๊พธ๋ ๊ฒ์ ๊ณ ๋ คํ ์ ์์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ ๊ฒ:
c#
public void AddEnumerableHashes<T>(IEnumerable<T> enumerable);
public void AddEnumerableHashes<T>(T[] array);
public void AddEnumerableHashes<T>(T[] array, int index, int length);
IEqualityComparers์๋ ์ค๋ฒ๋ก๋๊ฐ ํ์ํ์ง ๊ถ๊ธํฉ๋๋ค.
์ ์: ๋น๋ ๊ตฌ์กฐ์ฒด๊ฐ IEnumerable
๋ฅผ ๊ตฌํํ์ฌ ์ปฌ๋ ์
์ด๋์
๋ผ์ด์ ๊ตฌ๋ฌธ์ ์ง์ํ๋๋ก ํฉ๋๋ค.
C#
return new HashCode {
SomeField,
OtherField,
{ SomeString, StringComparer.UTF8 },
{ SomeHashSet, HashSet<int>.CreateSetComparer() }
}.GetHashCode()
์ด๊ฒ์ Add()
๋ฅผ ์ง์ ํธ์ถํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๋ ์ฐ์ํ๊ณ (ํนํ ์์ ๋ณ์๊ฐ ํ์ํ์ง ์์) ์ฌ์ ํ ํ ๋น์ด ์์ต๋๋ค.
@SLaks ์ด์ฉ๋ฉด ๋ ์ข์ ๊ตฌ๋ฌธ์ด https://github.com/dotnet/csharplang/issues/455๋ฅผ ๊ธฐ๋ค๋ฆด ์ ์์ผ๋ฏ๋ก(์ ์์ด ์ง์๋๋ค๊ณ ๊ฐ์ ) HashCode
๊ฐ ๊ฐ์ง IEnumerable
์ ๊ตฌํํ ํ์๊ฐ ์์ ๊ฒ์
๋๋ค.
์ฐ๋ฆฌ๋ GetHashCode()๋ฅผ ์ฌ์ ์ํ์ฌ ํด์ ์ฝ๋๋ฅผ ์์ฑํ์ง ์๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ์ด๋ ๋ช ๋ช ๋ฐฉ์๊ณผ ๋์ ๊ด์ ๋ชจ๋์์ ์ด์ํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค(GetHashCode()๋ ๊ณ์ฐ ๋์์ด ์๋ ๊ฐ์ฒด์ ํด์ ์ฝ๋๋ฅผ ๋ฐํํด์ผ ํจ).
GetHashCode
๊ฐ ๊ณ์ฐ๋ ํด์ ์ฝ๋๋ฅผ ๋ฐํํ์ง ์๋๋ค๋ ๊ฒ์ด ์ด์ํฉ๋๋ค. ์ด๊ฒ์ ๊ฐ๋ฐ์๋ค์ ํผ๋์ค๋ฝ๊ฒ ํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์๋ฅผ ๋ค์ด @SLaks๋ ์ด๋ฏธ ToHashCode
๋ฅผ ์ฌ์ฉํ๋ ๋์ ์ ์์์์ ์ด๋ฅผ ์ฌ์ฉํ์ต๋๋ค.
@justinvp GetHashCode()
์ด ๊ณ์ฐ๋ ํด์ ์ฝ๋๋ฅผ ๋ฐํํ์ง ์์ ๊ฒฝ์ฐ [Obsolete]
๋ฐ [EditorBrowsable(Never)]
ํฉ๋๋ค.
๋ฐ๋ฉด์ ๊ณ์ฐ๋ ํด์ ์ฝ๋๋ฅผ ๋ฐํํ๋ ๋ฐ์๋ ํด๊ฐ ๋์ง ์์ต๋๋ค.
@terrajobst
์ฐ๋ฆฌ๋ ํด์ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํด
GetHashCode()
๋ฅผ ์ฌ์ ์ํ์ง ์๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ์ด๋ ๋ช ๋ช ๋ฐฉ์๊ณผ ํ๋ ๊ด์ ๋ชจ๋์์ ์ด์ํ ๊ฒ์ ๋๋ค(GetHashCode()
๋ ๊ฐ์ฒด์ ํด์ ์ฝ๋๋ฅผ ๋ฐํํด์ผ ํฉ๋๋ค. ๊ณ์ฐ ์ค).
์, GetHashCode()
๋ ๊ฐ์ฒด์ ํด์ ์ฝ๋๋ฅผ ๋ฐํํด์ผ ํ์ง๋ง ๋ ํด์ ์ฝ๋๊ฐ ๋ฌ๋ผ์ผ ํ๋ ์ด์ ๊ฐ ์์ต๋๊น? ์ ๋ ์ธ์คํด์ค ์ดํ ์ฌ์ ํ ๋ง์ต๋๋ค HashCode
๊ฐ์ ๋ด๋ถ ์ํ๊ฐ์์ ๊ฐ์ ๊ฐ์ ๋ฐํํฉ๋๋ค GetHashCode()
.
@terrajobst ๋ฐฉ๊ธ ๊ทํ์ ์๊ฒฌ์ ๋ณด์์ต๋๋ค. ๋ต์ฅ์ด ๋ฆ์ด์ง ์ ์ ์ฉ์ํด ์ฃผ์๊ณ , ์๋ฌด๋ฐ๋ ๊ฐ์ง ์๋ ๊ฒ์ด ๋ ์๋ค ๊ฐ๋ค ํ ๋ฟ์ด๋ผ๊ณ ์๊ฐํด์ ์๋ฆผ์ ํ์ธํ๋ ๊ฒ์ด ๋๋ ์ต๋๋ค. ๊ทธ๋ ์ง ์์ ๋คํ์ ๋๋ค! :๋ฐ๋ค:
์ ๋ ์ด๊ฒ์ ์ ํํ๊ณ ์ฒ๋ฆฌ๋/๋ถํฌ ์ธก์ ์ ์ํํ๊ฒ ๋์ด ๊ธฐ์ฉ๋๋ค(์ด๊ฒ์ด "์ด ์์ญ์ ๋ํ ์์ ์ ๊ด์ฌ์ด ์์"์ ์๋ฏธํ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค). ํ์ง๋ง ์ฌ๊ธฐ์ ์๋ ๋ชจ๋ ๋๊ธ์ ๋ชจ๋ ์ฝ์ ์ ์๋๋ก ์ ์ ์๊ฐ์ ์ฃผ์ธ์.
@terrajobst
์ฐ๋ฆฌ๊ฐ ๋ฐ๊ฟ ์ ์์ต๋๊น?
public void Add<T>(T[] value);
public void Add<T>(T[] value, int index, int length);
public void Add(byte[] value);
public void Add(byte[] value, int index, int length);
์๊ฒ
public void AddRange<T>(T[] values);
public void AddRange<T>(T[] values, int index, int count);
public void AddRange<T>(T[] values, int index, int count, IEqualityComparer<T> comparer);
? @svick์ด ์ธ๊ธํ ๋์์ ํผํ๊ธฐ ์ํด Add
-> AddRange
๋ก ์ด๋ฆ์ ๋ณ๊ฒฝํ์ต๋๋ค. ๋ฐ์ดํธ๋ณ ์์
์ ์ํํด์ผ ํ๋ ๊ฒฝ์ฐ ๋ฉ์๋ ๋ด์์ typeof(T) == typeof(byte)
์ฌ์ฉ์ ์ ๋ฌธํํ ์ ์์ผ๋ฏ๋ก byte
์ค๋ฒ๋ก๋๋ฅผ ์ ๊ฑฐํ์ต๋๋ค. ๋ํ value
-> values
๋ฐ length
-> count
. ๋น๊ต์ ์ค๋ฒ๋ก๋๊ฐ ์๋ ๊ฒ๋ ์๋ฏธ๊ฐ ์์ต๋๋ค.
@terrajobst ๊ทธ ์ด์ ๋ฅผ ์๊ธฐ์์ผ ์ฃผ์๊ฒ ์ต๋๊น?
public void Add(string value);
public void Add(string value, StringComparison comparisonType);
์ฐ๋ฆฌ๊ฐ ๊ฐ์ง ๋ ํ์ํฉ๋๋ค
public void Add<T>(T value);
public void Add<T>(T value, IEqualityComparer<T> comparer);
?
@svic
@justinvp GetHashCode()๊ฐ ๊ณ์ฐ๋ ํด์ ์ฝ๋๋ฅผ ๋ฐํํ์ง ์์ ๊ฒฝ์ฐ [Obsolete] ๋ฐ [EditorBrowsable(Never)]๋ก ํ์๋์ด์ผ ํฉ๋๋ค.
:+1:
@terrajobst ํธ์ง: HashCode
-> int
์์ ToHashCode
๋ฉ์๋๊ฐ ์๋ ์์์ ๋ณํ์ผ๋ก ๋์๊ฐ ์ ์์ต๋๊น?ToHashCode
๊ด์ฐฎ์ต๋๋ค. ์๋ @CyrusNajmabadi ์ ์๋ต์ ์ฐธ์กฐํ์ญ์์ค.
@jamesqo StringComparison
๋ ์ด๊ฑฐํ์
๋๋ค.
๊ทธ๋ฌ๋ ์ฌ๋๋ค์ ๋์ ์ด์ ์์ํ๋ StringComparer
๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
HashCode -> int์์ ์์์ ๋ณํ์ผ๋ก ๋์๊ฐ์ ToHashCode ๋ฉ์๋๊ฐ ์์ ์ ์์ต๋๊น?
์ฐ๋ฆฌ๋ ์ด์ ๋ํด ๋ ผ์ํ๊ณ ํ์์์ ๋ฐ๋ํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ๋ฌธ์ ๋ ์ฌ์ฉ์๊ฐ ์ต์ข 'int'๋ฅผ ์ป์ ๋ ์ถ๊ฐ ์์ ์ด ์์ฃผ ์ํ๋๋ค๋ ๊ฒ์ ๋๋ค. ์ฆ, ํด์์ฝ๋์ ๋ด๋ถ๋ ์ข ์ข ๋ง๋ฌด๋ฆฌ ๋จ๊ณ๋ฅผ ์ํํ๊ณ ์์ฒด๋ฅผ ์๋ก์ด ์ํ๋ก ์ฌ์ค์ ํ ์ ์์ต๋๋ค. ์์์ ๋ณํ์ผ๋ก ๊ทธ๋ฐ ์ผ์ด ๋ฐ์ํ๋ฉด ์ด์ํ ๊ฒ์ ๋๋ค. ์ด ์์ ์ ์ํํ ๊ฒฝ์ฐ:
HashCode hc = ...
int i1 = hc;
int i2 = hc;
๊ทธ๋ฌ๋ฉด ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
๊ทธ๋ฐ ์ด์ ๋ก ์ฐ๋ฆฌ๋ ๋ช ์์ ๋ณํ๋ ์ข์ํ์ง ์์ต๋๋ค(์ฌ๋๋ค์ ๋ณํ์ ๋ด๋ถ ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ๊ฒ์ผ๋ก ์๊ฐํ์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค).
๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๊ฒ์ด ๋ฐ์ํ๊ณ ์์์ ๋ช ์์ ์ผ๋ก ๋ฌธ์ํํ ์ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ ์ฌ์ ์ผ๋ก ๋ง์ ๊ฒ์ ์ ๋ฌํ๊ธฐ ์ํด ์ด๋ฆ์ ์ง์ ํ ์๋ ์์ต๋๋ค. ์ฆ, "ToHashCodeAndReset"(์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ๋ํด ๊ฒฐ์ ํ์ง๋ง). ๊ทธ๋ฌ๋ ์ต์ํ ์ด ๋ฐฉ๋ฒ์ ์ฌ์ฉ์๊ฐ Intellisense์ ๊ฐ์ ํญ๋ชฉ์์ ๋ณผ ์ ์๋ ๋ช ํํ ๋ฌธ์๋ฅผ ๊ฐ์ง ์ ์์ต๋๋ค. ์ ํ์ ๊ฒฝ์ฐ๋ ๊ทธ๋ ์ง ์์ต๋๋ค.
typeof(T) == typeof(byte) ์ฌ์ฉ์ ์ ๋ฌธํํ ์ ์์ผ๋ฏ๋ก ๋ฐ์ดํธ ์ค๋ฒ๋ก๋๋ฅผ ์ ๊ฑฐํ์ต๋๋ค.
IIRC๋ ์ด๊ฒ์ด JIT ๊ด์ ์์ ์ณ์ง ์๋ค๋ ๊ฒ์ ๋ํ ์ฝ๊ฐ์ ์ฐ๋ ค๊ฐ ์์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ ๊ฐ ์ ํ์ด ์๋ "typeof()" ๊ฒฝ์ฐ์๋ง ํด๋น๋์์ ์ ์์ต๋๋ค. jit์ด value-type typeof() ๊ฒฝ์ฐ์ ๋ํด ํจ๊ณผ์ ์ผ๋ก ์ฌ๋ฐ๋ฅธ ์ผ์ ํ๋ ํ ๊ทธ๊ฒ์ ์ข์ ๊ฒ์ ๋๋ค.
@CyrusNajmabadi int
๋ก์ ๋ณํ์ ์ํ ๋ณ๊ฒฝ์ด ํฌํจ๋ ์ ์๋ค๋ ๊ฒ์ ๋ชฐ๋์ต๋๋ค. ToHashCode
๊ทธ๋ผ.
์ํธํ ๊ด์ ์ ๋ํด ์๊ฐํ๋ ์ฌ๋๋ค - http://tuprints.ulb.tu-darmstadt.de/2094/1/thesis.lehmann.pdf
@terrajobst , ๋ด ์๊ฒฌ( ์ฌ๊ธฐ ๋ถํฐ ์์)์ ์ฝ๊ณ ์กฐ์ ๋ API ๋ชจ์์ ์น์ธํ ์ง ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ ์๊ฐ์ด ์์์ต๋๊น? ๊ทธ๋ ๋ค๋ฉด ์ด๊ฒ์ด api-approved/up for grabs๋ก ํ์๋ ์ ์๊ณ ํด์ ์๊ณ ๋ฆฌ์ฆ ๊ฒฐ์ ์ ์์ํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
@blowdart , ๊ฐ์กฐํ๊ณ ์ถ์ ํน์ ๋ถ๋ถ์ด ์์ต๋๊น?
์์์ ๊ทธ๊ฒ์ ๋ํด ๋๋ฌด ๋ช ์์ ์ด์ง ์์์ ์๋ ์์ง๋ง HashDoS ์นจ์ ์ ๋ํด ๋ด๊ฐ ๋ชจ๋ฅด๋ ์ ์ผํ ๋น์ํธํ ํด์๋ Marvin๊ณผ SipHash์ ๋๋ค. ์ฆ, ์์์ ๊ฐ์ผ๋ก Murmur๋ฅผ ์๋ฉ(๋งํ์๋ฉด)ํ๋๋ผ๋ ์ฌ์ ํ ๊นจ์ ธ์ DoS์ ์ฌ์ฉํ
์์, ๋ฐฉ๊ธ ํฅ๋ฏธ๋กญ๊ฒ ๋ณด์๊ณ ์ด์ ๋ํ ๋ฌธ์๋ "์ํธํ ์๊ณ ๋ฆฌ์ฆ์ ํตํด ์์ฑ๋ ํด์ ์ฝ๋์๋ ์ฌ์ฉํ์ง ์์"์ด๋ผ๊ณ ๋์ ์์ด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๊ฒฐ์
AddRange
๋ฉ์๋๋ฅผ ์ ๊ฑฐํด์ผ ํฉ๋๋ค. ๋ฐฐ์ด์ ๋งค์ฐ ์์ฃผ ๋ํ๋ ๊ฐ๋ฅ์ฑ์ด ๋ค์ ๋ฎ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ผ๋จ ๋ ํฐ ๋ฐฐ์ด์ด ๊ด๋ จ๋๋ฉด ๋ฌธ์ ๋ ๊ณ์ฐ์ ์บ์ํด์ผ ํ๋์ง ์ฌ๋ถ์
๋๋ค. ํธ์ถ ์ธก์์ for ๋ฃจํ๋ฅผ ๋ณด๋ฉด ๊ทธ๊ฒ์ ๋ํด ์๊ฐํ ํ์๊ฐ ์์์ ๋ถ๋ช
ํ ์ ์ ์์ต๋๋ค.IEnumerable
์ค๋ฒ๋ก๋๋ฅผ AddRange
์ ์ถ๊ฐํ๊ณ ์ถ์ง ์์ต๋๋ค.string
์ StringComparison
๊ฐ ๊ฑธ๋ฆฌ๋ string
Add
๋ํ ์ค๋ฒ๋ก๋๊ฐ ํ์ํ์ง ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์, IEqualityComparer
ํตํด ํธ์ถํ๋ ๊ฒ๋ณด๋ค ๋ ํจ์จ์ ์ผ ์ ์์ง๋ง ๋์ค์ ์์ ํ ์ ์์ต๋๋ค.GetHashCode
๋ฅผ ์ค๋ฅ์ ํจ๊ป ์ฌ์ฉ๋์ง ์๋ ๊ฒ์ผ๋ก ํ์ํ๋ ๊ฒ์ ์ข์ ์๊ฐ์ด์ง๋ง ํ ๋จ๊ณ ๋ ๋์๊ฐ IntelliSense์์ ์จ๊ธธ ์๋ ์์ต๋๋ค.์ด๊ฒ์ ์ฐ๋ฆฌ์๊ฒ ๋ค์์ ๋จ๊น๋๋ค.
```C#
// ์ฝ์ด ์ด์
๋ธ๋ฆฌ์ ์์ ๊ฒ์
๋๋ค.
// .NET ํ๋ ์์ํฌ: mscorlib
// .NET ์ฝ์ด : System.Runtime / System.Private.CoreLib
๋ค์์คํ์ด์ค ์์คํ
{
๊ณต๊ฐ ๊ตฌ์กฐ์ฒด ํด์ ์ฝ๋
{
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public void Add<T>(T value);
public void Add<T>(T value, IEqualityComparer<T> comparer);
[Obsolete("Use ToHashCode to retrieve the computed hash code.", error: true)]
[EditorBrowsable(Never)]
public override int GetHashCode();
public int ToHashCode();
}
}
```
๋ค์ ๋จ๊ณ: ๋ฌธ์ ๋ ํด๊ฒฐ ํด์ผ ํฉ๋๋ค. ์ฌ๋ฌ ํ๋ณด ์๊ณ ๋ฆฌ์ฆ ์ ์คํ์ผ๋ก ์ฌ์ฉ https://github.com/dotnet/corefx/issues/14354#issuecomment -305028686 ๋ชฉ๋ก์ ์ฐธ์กฐ
๋ณต์ก์ฑ: ํผ
๋๊ตฐ๊ฐ ๊ทธ๊ฒ์ ๋ฐ๋ฆฌ๋ฌ ๊ด์ฌ์ด ์๋ค๋ฉด, ์ ํฌ์๊ฒ ping์ ๋ณด๋ด์ฃผ์ญ์์ค. ์ฌ๋ฌ ์ฌ๋์ด ํจ๊ป ์์ ํ ์ ์๋ ๊ณต๊ฐ๋ ์์ ์ ์์ต๋๋ค. ( @jamesqo ๋น์ ์ ์ด์์ ๊ฐ์ฅ ๋ง์ ์๊ฐ์ ํฌ์ํ ๋งํผ ์ฐ์ ์์๊ฐ ์์ต๋๋ค.)
@karelz ์์ ์๊ฒฌ์๋ ๋ถ๊ตฌํ๊ณ ์ต๊ณ ์ ํด์ ์๊ณ ๋ฆฌ์ฆ์ ์ ํํ ์๊ฒฉ์ด ์๋ค๊ณ ์๊ฐํ๊ธฐ ๋๋ฌธ์ ๋ง์์ด ๋ฐ๋์์ต๋๋ค. @morganbr์ด ๋์ด๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค ์ผ๋ถ๋ฅผ ์ดํด๋ณด๊ณ ๊ตฌํ์ด ๋งค์ฐ ๋ณต์ก ํ๋ค๋ ๊ฒ์ ๊นจ๋ฌ์์ต๋๋ค. ๊ทธ๋์ ์ง์ ํ ์คํธํ๊ธฐ ์ํด ์ด๋ฅผ C#์ผ๋ก ์ฝ๊ฒ ๋ณํํ ์ ์์ต๋๋ค. ์ ๋ C++์ ๋ํ ๋ฐฐ๊ฒฝ ์ง์์ด ๊ฑฐ์ ์๊ธฐ ๋๋ฌธ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํ๊ณ ํ ์คํธ ์ฑ์ ์์ฑํ๋ ๊ฒ๋ง์ผ๋ก๋ ์ด๋ ค์์ ๊ฒช์ ๊ฒ์ ๋๋ค.
๊ทธ๋ฌ๋ ์ด๊ฒ์ด ์ต์ ๋ชฉ๋ก์ ์์ํ ๋จ์ ์๊ธฐ๋ฅผ ์ํ์ง ์์ต๋๋ค. ์ค๋๋ถํฐ ์ผ์ฃผ์ผ ๋์ ์๋ฌด๋ ํด๊ฒฐํ์ง ์์ผ๋ฉด Programmers SE ๋๋ Reddit์ ์ง๋ฌธ์ ๊ฒ์ํ๋ ๊ฒ์ ๊ณ ๋ คํ ๊ฒ์ ๋๋ค.
๋๋ ๊ทธ๊ฒ์ ๋ฒค์น๋งํนํ์ง ์์์ง๋ง (๋๋ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ๊ทธ๊ฒ์ ์ต์ ํํ์ง๋ ์์์ง๋ง) ๋ค์์ ์ฌ๋ฌ ๊ฐ์ธ ํ๋ก์ ํธ์์ ์ฌ์ฉํ๋ Murmur3 ํด์ ์๊ณ ๋ฆฌ์ฆ์ ๊ธฐ๋ณธ ๊ตฌํ์ ๋๋ค. https://gist.github.com/tannergooding/0a12559d1a912068b9aeb4b9586aad7f
์ฌ๊ธฐ์์ ๊ฐ์ฅ ์ต์ ์ ์๋ฃจ์ ์ ์ ๋ ฅ ๋ฐ์ดํฐ์ ํฌ๊ธฐ์ ๋ฐ๋ผ ํด์ฑ ์๊ณ ๋ฆฌ์ฆ์ ๋์ ์ผ๋ก ๋ณ๊ฒฝํ๋ ๊ฒ์ ๋๋ค.
์: Mumur3(๋ฐ ๊ธฐํ)๋ ๋๊ท๋ชจ ๋ฐ์ดํฐ ์งํฉ์ ๋ํด ๋งค์ฐ ๋น ๋ฅด๊ณ ํ๋ฅญํ ๋ถํฌ๋ฅผ ์ ๊ณตํ์ง๋ง ๋ ์์ ๋ฐ์ดํฐ ์งํฉ์ ๋ํด์๋ '์ ์กฐํ'(๋ฐฐํฌ ๋ฐฉ์์ด ์๋๋ผ ์๋ ์ธก๋ฉด์์) ์ํํ ์ ์์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ด ํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ ์ฒด ๋ฐ์ดํธ ์๊ฐ X๋ณด๋ค ์์ผ๋ฉด ์๊ณ ๋ฆฌ์ฆ A๋ฅผ ์ํํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์๊ณ ๋ฆฌ์ฆ B๋ฅผ ์ํํ์ญ์์ค. ์ด๊ฒ์ ์ฌ์ ํ โโ๊ฒฐ์ ๋ก ์ ์ด์ง๋ง(์คํ๋น) ์ ๋ ฅ ๋ฐ์ดํฐ์ ์ค์ ํฌ๊ธฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์๋์ ๋ถํฌ๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค.
์ธ๊ธ๋ ์๊ณ ๋ฆฌ์ฆ ์ค ์ผ๋ถ๋ SIMD ๋ช
๋ น์ด๋ฅผ ์ํด ํน๋ณํ ์ค๊ณ๋ ๊ตฌํ์ ๊ฐ์ง๊ณ ์์ผ๋ฏ๋ก ๊ฐ์ฅ ์ฑ๋ฅ์ด ์ข์ ์๋ฃจ์
์ ์ผ๋ถ ์์ค์์ FCALL์ ํฌํจํ ๊ฐ๋ฅ์ฑ์ด ๋๊ฑฐ๋(์: ์ผ๋ถ BufferCopy ๊ตฌํ์์ ์ํ๋จ) ์ข
์์ฑ์ ์ทจํ๋ ๊ฒ์ ํฌํจํ ์ ์์ต๋๋ค. System.Numerics.Vector
@jamesqo , ์ ํ์ ๋์์ ๋๋ฆฌ๊ฒ ์ต๋๋ค. ๊ฐ์ฅ ๋์์ด ํ์ํ ๊ฒ์ ํ๋ณด ๊ตฌํ์ ์ํ ์ฑ๋ฅ ๋ฐ์ดํฐ์ ๋๋ค( @tannergooding์ด ์ง์ ํ๋ฏ์ด ์ผ๋ถ ์๊ณ ๋ฆฌ์ฆ์๋ ํน๋ณํ ์ปดํ์ผ๋ฌ ์ง์์ด ํ์ํ์ง๋ง ์ด์์ ์ผ๋ก๋ C#). ์์์ ์ธ๊ธํ๋ฏ์ด ์ ํ๋์ง ์์ ํ๋ณด์๋ฅผ ๋น๋ํ๋ฉด ๋์ค์ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก ์์ ์ด ๋ญ๋น๋๋ ๊ฒ์ ๋ํด ๊ฑฑ์ ํ์ง ๋ง์ญ์์ค.
๋ค์ํ ๊ตฌํ์ ์ํ ๋ฒค์น๋งํฌ๊ฐ ์๋ค๋ ๊ฒ์ ์๊ณ ์์ง๋ง ์ด API์ ๊ฐ๋ฅํ ์ ๋ ฅ ๋ฒ์(์: 1-10 ํ๋๊ฐ ์๋ ๊ตฌ์กฐ์ฒด)๋ฅผ ์ฌ์ฉํ์ฌ ๋น๊ตํ๋ ๊ฒ์ด ์ค์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
@tannergooding , ๊ทธ๋ฐ ์ข ๋ฅ์ ์ ์์ฑ์ด ๊ฐ์ฅ ์ฑ๋ฅ์ด ์ข์ ์ ์์ง๋ง ์ผ๋ง๋ ๋ง์ด ํธ์ถ๋ ์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ Add ๋ฉ์๋์ ํจ๊ป ์๋ํ๋์ง ์ ์ ์์ต๋๋ค. Combine์ผ๋ก ํ ์ ์์ง๋ง, ์ด๋ ์ผ๋ จ์ Add ํธ์ถ์ด ํด๋น Combine ํธ์ถ๊ณผ ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํ ์ ์์์ ์๋ฏธํฉ๋๋ค.
๋ํ ๊ฐ์ฅ ๊ฐ๋ฅ์ฑ์ด ๋์ ์
๋ ฅ ๋ฒ์๊ฐ 4-32๋ฐ์ดํธ( Combine`1
- Combine`8
)์ธ ๊ฒฝ์ฐ ํด๋น ๋ฒ์์์ ํฐ ์ฑ๋ฅ ๋ณํ๊ฐ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
๊ทธ๋ฐ ์ข ๋ฅ์ ์ ์์ฑ์ด ๊ฐ์ฅ ์ฑ๋ฅ์ด ์ข์ ์ ์์ง๋ง ์ผ๋ง๋ ๋ง์ด ํธ์ถ๋ ์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ Add ๋ฉ์๋์ ํจ๊ป ์๋ํ๋ ๋ฐฉ๋ฒ์ ์ ์ ์์ต๋๋ค.
๋๋ ๊ฐ์ธ์ ์ผ๋ก API ๋ชจ์์ด ๋ฒ์ฉ ํด์ฑ์ ๋งค์ฐ ์ ํฉํ๋ค๊ณ ํ์ ํ์ง ์์ต๋๋ค(๊ทธ๋ฌ๋ ๊ฐ๊น์ต๋๋ค)...
ํ์ฌ ์ฐ๋ฆฌ๋ ์ ์ ์์ฑ์ ์ํ Combine
๋ฉ์๋๋ฅผ ๊ณต๊ฐํ๊ณ ์์ต๋๋ค. ์ด๊ฒ์ด ๋ชจ๋ ์
๋ ฅ์ ๊ฒฐํฉํ๊ณ ์ต์ข
ํด์ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํ ๊ฒ์ด๋ผ๋ฉด ์ด๋ฆ์ 'poor'์ด๊ณ Compute
์ ๊ฐ์ ๊ฒ์ด ๋ ์ ์ ํ ์ ์์ต๋๋ค.
Combine
๋ฉ์๋๋ฅผ ๋
ธ์ถํ๋ ๊ฒฝ์ฐ ๋ชจ๋ ์
๋ ฅ์ ํผํฉํด์ผ ํ๋ฉฐ ์ฌ์ฉ์๋ Finalize
๋ฉ์๋๋ฅผ ํธ์ถํด์ผ ํฉ๋๋ค. ์ด ๋ฉ์๋๋ ๋ง์ง๋ง ๊ฒฐํฉ์ ์ถ๋ ฅ๊ณผ ์ด ๋ฐ์ดํธ ์๋ฅผ ์ทจํด์ผ ํฉ๋๋ค. ๊ฒฐํฉํ์ฌ ์ต์ข
ํด์ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค(ํด์ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ์ ๋นํธ๋ฅผ ๋์ฌํ๋ก ๋ง๋๋ ์์ธ์ด ๋๊ธฐ ๋๋ฌธ์ ์ค์ํฉ๋๋ค).
๋น๋ ํจํด์ ๊ฒฝ์ฐ Add
๋ฐ ToHashCode
๋ฉ์๋๋ฅผ ๋
ธ์ถํฉ๋๋ค. Add
๋ฉ์๋๊ฐ ๋ฐ์ดํธ๋ฅผ ์ ์ฅํ๊ณ ToHashCode
์ ๋ํ ํธ์ถ์์๋ง ๊ฒฐํฉ/์ข
๋ฃํ๊ธฐ ์ํ ๊ฒ์ธ์ง(์ด ๊ฒฝ์ฐ ์ฌ๋ฐ๋ฅธ ์๊ณ ๋ฆฌ์ฆ์ ๋์ ์ผ๋ก ์ ํํ ์ ์์) ์ฆ์์์ ๊ฒฐํฉํด์ผ ํ๋ ๊ฒฝ์ฐ์๋ ์ด๋ฌํ ๊ฒฝ์ฐ๊ฐ ๋ถ๋ช
ํด์ผ ํฉ๋๋ค(๊ทธ๋ฆฌ๊ณ ๊ตฌํ์ ๊ฒฐํฉ๋ ๋ฐ์ดํธ์ ์ด ํฌ๊ธฐ๋ฅผ ๋ด๋ถ์ ์ผ๋ก ์ถ์ ํด์ผ ํจ).
๋ ๋ณต์กํ ์์์ ์ ์ฐพ๋ ์ฌ๋์ xxHash32๋ฅผ ์ฌ์ฉํด ๋ณด์ญ์์ค. ๊ทธ๊ฒ์ C#์ผ๋ก ๊ฝค ์ฝ๊ฒ ๋ฒ์ญ๋ ๊ฒ์ ๋๋ค( ์ฌ๋๋ค์ด ํด๋์ต๋๋ค ).
์ฌ์ ํ ๋ก์ปฌ์์ ํ ์คํธํ๊ณ ์์ง๋ง Murmur3์ C# ๊ตฌํ์ ๋ํด ๋ค์๊ณผ ๊ฐ์ ์ฒ๋ฆฌ๋ ์๋๋ฅผ ๋ณด๊ณ ์์ต๋๋ค.
๋ค์์ 1-8 ์ ๋ ฅ์ ๋ํ ์ ์ Combine ๋ฉ์๋์ ๋ํ ๊ฒ์ ๋๋ค.
1070.18 mb/s
1511.49 mb/s
1674.89 mb/s
1957.65 mb/s
2083.24 mb/s
2140.94 mb/s
2190.27 mb/s
2245.53 mb/s
๋ด ๊ตฌํ์์๋ GetHashCode
๊ฐ ๊ฐ ์
๋ ฅ์ ๋ํด ํธ์ถ๋์ด์ผ ํ๊ณ ๊ณ์ฐ๋ ๊ฐ์ด ๋ฐํ๋๊ธฐ ์ ์ ๋ง๋ฌด๋ฆฌ๋์ด์ผ ํ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
ํ
์คํธํ๊ธฐ ๊ฐ์ฅ ๊ฐ๋จํ int
๊ฐ์ ๊ฒฐํฉํ์ต๋๋ค.
์ฒ๋ฆฌ๋์ ๊ณ์ฐํ๊ธฐ ์ํด 10,001๋ฒ์ ๋ฐ๋ณต์ ์คํํ๊ณ ์ฒซ ๋ฒ์งธ ๋ฐ๋ณต์ '์๋ฐ์ ' ์คํ์ผ๋ก ๋ฒ๋ ธ์ต๋๋ค.
๊ฐ ๋ฐ๋ณต์์ HashCode.Combine
ํธ์ถํ๋ 10,000๊ฐ์ ํ์ ๋ฐ๋ณต์ ์คํํ๊ณ ๋ค์ ๋ฐ๋ณต์ ์ฒซ ๋ฒ์งธ ์
๋ ฅ ๊ฐ์ผ๋ก ์ด์ ํ์ ๋ฐ๋ณต์ ๊ฒฐ๊ณผ๋ฅผ ์ ๋ฌํฉ๋๋ค.
๊ทธ๋ฐ ๋ค์ ํ๊ท ๊ฒฝ๊ณผ ์๊ฐ์ ์ป๊ธฐ ์ํด ๋ชจ๋ ๋ฐ๋ณต์ ํ๊ท ์ ๊ตฌํ๊ณ , ์ด๋ฅผ ๋ฃจํ๋น ์คํ๋๋ ํ์ ๋ฐ๋ณต ์๋ก ๋ ๋๋์ด ํธ์ถ๋น ํ๊ท ์๊ฐ์ ๊ตฌํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ด๋น ์ํํ ์ ์๋ ํธ์ถ ์๋ฅผ ๊ณ์ฐํ๊ณ ์ฌ๊ธฐ์ ์ค์ ์ฒ๋ฆฌ๋์ ๊ณ์ฐํ๊ธฐ ์ํด ๊ฒฐํฉ๋ ๋ฐ์ดํธ ์๋ฅผ ๊ณฑํฉ๋๋ค.
์ฝ๋๋ฅผ ์ ๋ฆฌํ๊ณ ์ ์ ํ์ ๊ณต์ ํฉ๋๋ค.
@tannergooding , ๋๋จํ ์ง์ ์ธ ๊ฒ ๊ฐ์ต๋๋ค. ์ฌ๋ฐ๋ฅธ ์ธก์ ๊ฐ์ ์ป๊ณ ์๋์ง ํ์ธํ๊ธฐ ์ํด API์ ์๋๋ HashCode.Combine(a, b)
์ ๋ํ ํธ์ถ์ด ํธ์ถํ๋ ๊ฒ๊ณผ ๋์ผํ๋ค๋ ๊ฒ์
๋๋ค.
HashCode hc = new HashCode();
hc.Add(a); // Initializes the hash state, calls a.GetHashCode() and feeds the result into the hash state
hc.Add(b); // Calls b.GetHashCode() and feeds the result into the hash state
return hc.ToHashCode(); // Finalizes the hash state, truncates it to an int, resets the internal state and returns the int
๋ ๊ฒฝ์ฐ ๋ชจ๋ ๋ฐ์ดํฐ๋ ๋์ผํ ๋ด๋ถ ํด์ ์ํ๋ก ๊ณต๊ธ๋์ด์ผ ํ๋ฉฐ ํด์๋ ๋ง์ง๋ง์ ํ ๋ฒ ์ข ๋ฃ๋์ด์ผ ํฉ๋๋ค.
๐
๊ทธ๊ฒ์ด ๋ด๊ฐ ์์ฑํ ์ฝ๋๊ฐ ํ๋ ์ผ์
๋๋ค. ์ ์ผํ ์ฐจ์ด์ ์ ๋ชจ๋ ์ฝ๋๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์ธ๋ผ์ธํ๋ค๋ ๊ฒ์
๋๋ค( new HashCode()
๋ฅผ ํ ๋นํ๊ณ ์์์ด๊ธฐ ๋๋ฌธ์ ๊ฒฐํฉ๋ ๋ฐ์ดํธ ์๋ฅผ ์ถ์ ํ ํ์๊ฐ ์์ต๋๋ค).
@morganbr. Murmur3์ ๋ํ ๊ตฌํ + ์ฒ๋ฆฌ๋ ํ ์คํธ: https://gist.github.com/tannergooding/89bd72f05ab772bfe5ad3a03d6493650
MurmurHash3๋ ์ฌ๊ธฐ์ ์ค๋ช ๋ ์๊ณ ๋ฆฌ์ฆ์ ๊ธฐ๋ฐ์ผ๋ก ํฉ๋๋ค. https://github.com/aappleby/smhasher/wiki/MurmurHash3 , repo๋ MIT๋ผ๊ณ ๋งํฉ๋๋ค.
xxHash32(BSD-2 ์กฐํญ -- https://github.com/Cyan4973/xxHash/blob/dev/xxhash.c) ๋ฐ SpookyHash(๊ณต๊ฐ ๋๋ฉ์ธ -- http://www.burtleburtle.net/bob/hash) ์์ /spooky.html) ๋ณํ
@tannergooding ๋ค์ ๋งํ์ง๋ง, ํด์ ์ ๋ฌธ๊ฐ๋ ์๋์ง๋ง Murmur๊ฐ DoS์ ์ ํญํ์ง ์๋๋ค๊ณ ๋งํ [๊ธฐ์ฌ ์ฝ๊ธฐ][1]๋ฅผ ๊ธฐ์ตํ๋ฏ๋ก ์ ํํ๊ธฐ ์ ์ ์ด๋ฅผ ์ง์ ํ์ต๋๋ค.
@jamesqo , ๋ด๊ฐ ํ๋ฆด ์๋ ์์ง๋ง Murmur3์ด ์๋ Murmur2์ ์ทจ์ฝ์ ์ด ์ ์ฉ๋์๋ค๊ณ ํ์ ํฉ๋๋ค.
๋ ๊ฒฝ์ฐ ๋ชจ๋ C#์ ๋ํ ์ฒ๋ฆฌ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋๋ก ์ฌ๋ฌ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํ๊ณ ์์ต๋๋ค. ์ด๋ฌํ ์๊ณ ๋ฆฌ์ฆ์ ๋ถํฌ ๋ฐ ๊ธฐํ ์์ฑ์ ์๋นํ ์ ์๋ ค์ ธ ์์ผ๋ฏ๋ก ๋์ค์ ์ด๋ค ๊ฒ์ด ๊ฐ์ฅ ์ข์์ง ๊ณ ๋ฅผ ์ ์์ต๋๋ค ๐
์ด๋ฐ, ๊ธฐ์ฌ ๋งํฌ๋ฅผ ์์์ต๋๋ค: http://emboss.github.io/blog/2012/12/14/breaking-murmur-hash-flooding-dos-reloaded/.
@tannergooding ์๊ฒ ์ต๋๋ค. ๊ณต์ ํ ์๋ฆฌ :+1:
@tannergooding , Murmur3 ๊ตฌํ์ ์ดํด๋ณด์๋๋ฐ ์ผ๋ฐ์ ์ผ๋ก ์ณ๊ณ ์ต์ ํ๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ด๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ดํดํ๋์ง ํ์ธํ๊ธฐ ์ํด CombinedValue์ Murmur์ ๋ด๋ถ ์ํ๊ฐ ๋ชจ๋ 32๋นํธ๋ผ๋ ์ฌ์ค์ ์ฌ์ฉํ๊ณ ์์ต๋๊น? ์ด๊ฒ์ ์๋ง๋ ์ด ๊ฒฝ์ฐ์ ๋ํด ๊ฝค ์ข์ ์ต์ ํ์ผ ๊ฒ์ด๋ฉฐ ๋ด๊ฐ ์ด์ ์ ํผ๋ํ๋ ์ผ๋ถ๋ฅผ ์ค๋ช ํฉ๋๋ค.
์ฐ๋ฆฌ๊ฐ ๊ทธ๊ฒ์ ์ฑํํ๋ ค๋ฉด ๋ช ๊ฐ์ง ์กฐ์ ์ด ํ์ํ ์ ์์ต๋๋ค (์๋ง๋ ์ฑ๋ฅ ์ธก์ ์ ํฐ ์ฐจ์ด๋ ์์ ๊ฒ์ ๋๋ค).
๊ทธ๋์ ๋ด๊ฐ ์ด API๋ฅผ ๊ฐ๋งํ๋ฉด์ (field1, field2, field3).GetHashCode()
๋ฅผ ํตํด GetHashCode๋ฅผ ๊ตฌํํ๋ ๊ฒ์ด ์ผ๋ง๋ ๋๋นด์ต๋๊น?
@jnm2 , ValueTuple ํด์ ์ฝ๋ ๊ฒฐํฉ๊ธฐ๋ ํด์ ์ฝ๋์์ ์ ๋ ฅ์ ์์๋๋ก ์ ๋ ฅํ๋ ๊ฒฝํฅ์ด ์์ต๋๋ค(๊ฐ์ฅ ์ต๊ทผ์ ๋์จ ๊ฒ์ ๋ฒ๋ฆฝ๋๋ค). ์์๋ก ๋๋๋ ๋ช ๊ฐ์ ํ๋์ ํด์ ํ ์ด๋ธ์ ๊ฒฝ์ฐ ๋์น์ฑ์ง ๋ชปํ ์๋ ์์ต๋๋ค. ๋ง์ ํ๋ ๋๋ 2์ ๊ฑฐ๋ญ์ ๊ณฑ์ผ๋ก ๋๋๋ ํด์ ํ ์ด๋ธ์ ๊ฒฝ์ฐ ์ฝ์ ํ ๋ง์ง๋ง ํ๋์ ์ํธ๋กํผ๊ฐ ์ถฉ๋ ์ฌ๋ถ์ ๊ฐ์ฅ ํฐ ์ํฅ์ ๋ฏธ์นฉ๋๋ค(์: ๋ง์ง๋ง ํ๋๊ฐ bool ๋๋ ์์ int์ธ ๊ฒฝ์ฐ guid๋ผ๋ฉด ์๋ง๋ ์ถฉ๋์ด ๋ง์ด ์ผ์ด๋ ๊ฒ์ ๋๋ค.
ValueTuple์ ๋ชจ๋ 0์ธ ํ๋์์๋ ์ ์๋ํ์ง ์์ต๋๋ค.
์ฐธ๊ณ ๋ก ์ ๋ ๋ค๋ฅธ ๊ตฌํ ์์ ์ ์ค๋จํด์ผ ํ์ต๋๋ค(์ฐ์ ์์๊ฐ ๋ ๋์ ์์ ์ด ์์). ์ธ์ ๋ค์ ๊ฐ์ ธ์ฌ ์ ์์์ง ๋ฏธ์ง์์ ๋๋ค.
๋ฐ๋ผ์ ๊ตฌ์กฐํ๋ ์ ํ์ ๋ํด ์ถฉ๋ถํ์ง ์์ ๊ฒฝ์ฐ ํํ์ ๋ํด ์ถฉ๋ถํ ์ด์ ๋ ๋ฌด์์ ๋๊น?
@jnm2 , ์ด๊ฒ์ด ์ด ๊ธฐ๋ฅ์ด ๊ตฌ์ถํ ๊ฐ์น๊ฐ ์๋ ํ ๊ฐ์ง ์ด์ ์ ๋๋ค. ๋ฐ๋ผ์ ํ๋ ์์ํฌ ์ ์ฒด์์ ํ์ค ์ดํ์ ํด์๋ฅผ ๊ต์ฒดํ ์ ์์ต๋๋ค.
์ฑ๋ฅ ๋ฐ ํ์ง ํน์ฑ์ด ์๋ ๋๊ท๋ชจ ํด์ ํจ์ ํ
์ด๋ธ:
https://github.com/leo-yuriev/t1ha
@arespr ํ์ด ํด์ ํจ์์ C# ๊ตฌํ์ ์ฐพ๊ณ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋๋ ๊ณต์ ํด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.
@tannergooding ์ฌ์ ํ ์ด ๋ฌธ์ ๋ฅผ ๋ฐฑ์ ํ ์ ์์ต๋๊น? ๊ทธ๋ ๋ค๋ฉด ํด์ ์ ๋ฌธ๊ฐ๋ฅผ ์ฐพ๊ณ ์๋ค๊ณ Reddit/Twitter์ ๊ฒ์ํ๊ฒ ์ต๋๋ค.
ํธ์ง: Reddit์ ๊ฒ์๋ฌผ์ ์์ฑํ์ต๋๋ค. https://www.reddit.com/r/csharp/comments/6qsysm/looking_for_hash_expert_to_help_net_core_team/?ref=share&ref_source=link
@jamesqo , ๋ด ์ ์์ ๋ช ๊ฐ์ง ๋ ๋์ ์ฐ์ ์์๊ฐ ์์ผ๋ฉฐ ์์ผ๋ก 3์ฃผ ์ด๋ด์ ์ด ์์ ์ ์ํํ ์ ์์ต๋๋ค.
๋ํ ํ์ฌ ์ธก์ ๊ฐ์ ํ์ฌ C#์์ ์ฝ๋ฉํ ์ ์๋ ํญ๋ชฉ์ผ๋ก ์ ํ๋์ง๋ง, ์ด๊ฒ์ด ์ค์ ๋ก ์ ์ฉ๋๋ ๊ฒฝ์ฐ(https://github.com/dotnet/designs/issues/13), ์ธก์ ๊ฐ์ด ๋ค์ ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค. ;)
๋ํ ํ์ฌ ์ธก์ ๊ฐ์ ํ์ฌ C#์์ ์ฝ๋ฉํ ์ ์๋ ํญ๋ชฉ์ ๋ฐ๋ผ ์ ํ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ด ์ผ์ด ๋๋ฉด(dotnet/designs#13) ์ธก์ ๊ฐ์ด ๋ค์ ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค.)
๊ด์ฐฎ์ต๋๋ค. ๋ด์ฅ ํจ์๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ฉด ํด์ ์๊ณ ๋ฆฌ์ฆ์ ํญ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ํด์ ์ฝ๋๋ฅผ ์บก์ํ/๋ฌด์์ํํ๋ฉด ๊ทธ๋ ๊ฒ ํ ์ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ํ์ฌ ์ํ์์ ๋ฐํ์์ ๋ํด ์ต๊ณ ์ ์ฑ๋ฅ/๋ฐฐํฌ ํธ๋ ์ด๋์คํ๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ ์ฐพ๊ณ ์์ต๋๋ค.
@jamesqo , ๋์์ค ์ฌ๋๋ค์ ์ฐพ์์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ํด์ ์ ๋ฌธ๊ฐ๊ฐ ์๋ ์ฌ๋๋ ์ด ์์ ์ ํ๊ฒ ๋์ด ๊ธฐ์ฉ๋๋ค. ๋ค๋ฅธ ์ธ์ด๋ ๋์์ธ์์ ์ผ๋ถ ์๊ณ ๋ฆฌ์ฆ์ C#์ผ๋ก ์ด์ํ ๋ค์ ์ฑ๋ฅ ์ธก์ ์ ์ํํ ์ ์๋ ์ฌ๋์ด ์ ๋ง ํ์ํฉ๋๋ค. ํ๋ณด๋ฅผ ์ ํํ๋ฉด ์ ๋ฌธ๊ฐ๊ฐ ๋ณ๊ฒฝ ์ฌํญ์ ๋ํด ์ํํ ๊ฒ์ ๋๋ค. ์ฝ๋์ ์ ํ์ฑ, ์ฑ๋ฅ, ๋ณด์ ๋ฑ์ ๊ฒํ ํฉ๋๋ค.
์๋
ํ์ธ์! ๋๋ ๋ฐฉ๊ธ ํ ๋ก ์ ์ฝ์๊ณ ์ ์ด๋ ๋์๊ฒ๋ murmur3-32 PoC์ ์ฐฌ์ฑํ์ฌ ์ฌ๊ฑด์ด ๊ฐ๋ ฅํ๊ฒ ์ข
๊ฒฐ๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ด๋ค BTW๊ฐ ๋์๊ฒ ๋งค์ฐ ์ข์ ์ ํ์ผ๋ก ๋ณด์ด๋ฉฐ ๋ ์ด์ ๋ถํ์ํ ์์
์ ์ง์ถํ์ง ์๋ ๊ฒ์ด ์ข์ต๋๋ค(ํ์ง๋ง .Add()
ํ์์ ์ญ์ ํ ์๋ ์์ต๋๋ค...).
๊ทธ๋ฌ๋ ๋๊ตฐ๊ฐ๊ฐ ๋ ๋ง์ ์ฑ๋ฅ ์์ ์ ๊ณ์ํ๊ธฐ๋ฅผ ์ํ๋ ๊ฒฝ์ฐ์๋ xx32, xx64, hsip13/24, seahash, murmur3-x86/32์ ๋ํ ์ผ๋ถ ์ฝ๋๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. ์ต์ ํ๋์ง ์์) sip13/24, spookyv2. City์ ์ผ๋ถ ๋ฒ์ ์ ํ์ํ ๊ฒฝ์ฐ ์ด์ํ๊ธฐ์ ์ถฉ๋ถํ ์ฌ์ ๋ณด์ ๋๋ค. ๊ทธ ๋ฐ์ฏค ๋ฒ๋ ค์ง ํ๋ก์ ํธ๋ ์ฝ๊ฐ ๋ค๋ฅธ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ผ๋์ ๋์๊ธฐ ๋๋ฌธ์ ์ ์๋ API์๋ HashCode ํด๋์ค๊ฐ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ฒค์น๋งํน์ ์ํด์๋ ๊ทธ๋ค์ง ์ค์ํ์ง ์์ต๋๋ค.
Definitlyํ์ง ์์ฐ ์ค๋น : ์ฝ๋๋ฅผ ๋ณต์ฌ ํ์คํ, ๊ณต๊ฒฉ์ ์ธ ์ธ๋ผ์ธ ๋ฐ ์์ ์ ์ ์คํ๋กค๊ณผ ๊ฐ์ ๋ฌด์ฐจ๋ณ์ ๊ด๋ ํ ๊ธ์ก์ ์ ์ฉ; ์๋์์ ์กด์ฌํ์ง ์์ผ๋ฉฐ ์ ๋ ฌ๋์ง ์์ ์ฝ๊ธฐ๋ ์์ต๋๋ค. ref-impl ํ ์คํธ ๋ฒกํฐ์ ๋ํ ํ ์คํธ์กฐ์ฐจ๋ ์๊ณกํ๊ฒ "๋ถ์์ "ํฉ๋๋ค.
์ด๊ฒ์ด ์กฐ๊ธ์ด๋ผ๋ ๋์์ด ๋๋ค๋ฉด ์์ผ๋ก 2์ฃผ ๋์ ๊ฐ์ฅ ์ฌ๊ฐํ ๋ฌธ์ ๋ฅผ ์์ ํ๊ณ ์ฝ๋์ ์ผ๋ถ ์๋น ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฉํ ์ ์๋ ์ถฉ๋ถํ ์๊ฐ์ ํ๋ณดํด์ผ ํฉ๋๋ค.
@๊นํ
๋๋ ๋ฐฉ๊ธ ํ ๋ก ์ ์ฝ์๊ณ ์ ์ด๋ ๋์๊ฒ๋ murmur3-32 PoC์ ์ฐฌ์ฑํ์ฌ ์ฌ๊ฑด์ด ๊ฐ๋ ฅํ๊ฒ ์ข ๊ฒฐ๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ด๋ค BTW๊ฐ ๋์๊ฒ ๋งค์ฐ ์ข์ ์ ํ์ผ๋ก ๋ณด์ด๋ฉฐ ๋ ์ด์ ๋ถํ์ํ ์์ ์ ์ง์ถํ์ง ์๋ ๊ฒ์ด ์ข์ต๋๋ค.
์๋์, ์ฌ๋๋ค์ ์์ง Murmur3๋ฅผ ์ ํธํ์ง ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ฑ๋ฅ/๋ฐฐํฌ ๊ฐ์ ๊ท ํ ์ธก๋ฉด์์ ์ ๋์ ์ผ๋ก ์ต๊ณ ์ ์๊ณ ๋ฆฌ์ฆ์ ์ ํํ๊ณ ์๋์ง ํ์ธํ๊ณ ์ถ์ต๋๋ค.
๊ทธ๋ฌ๋ ๋๊ตฐ๊ฐ๊ฐ ๋ ๋ง์ ์ฑ๋ฅ ์์ ์ ๊ณ์ํ๊ธฐ๋ฅผ ์ํ๋ ๊ฒฝ์ฐ์๋ xx32, xx64, hsip13/24, seahash, murmur3-x86/32์ ๋ํ ์ผ๋ถ ์ฝ๋๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. ์ต์ ํ๋์ง ์์) sip13/24, spookyv2. City์ ์ผ๋ถ ๋ฒ์ ์ ํ์ํ ๊ฒฝ์ฐ ์ด์ํ๊ธฐ์ ์ถฉ๋ถํ ์ฌ์ ๋ณด์ ๋๋ค.
์, ๋ถํํฉ๋๋ค! ์ฐ๋ฆฌ๋ ํ ์คํธํ ๊ฐ๋ฅํ ๋ง์ ์๊ณ ๋ฆฌ์ฆ์ ๋ํ ์ฝ๋๋ฅผ ์์งํ๊ณ ์ ํฉ๋๋ค. ๋น์ ์ด ๊ธฐ์ฌํ ์ ์๋ ๋ชจ๋ ์๋ก์ด ์๊ณ ๋ฆฌ์ฆ์ ๊ฐ์น๊ฐ ์์ต๋๋ค. City ์๊ณ ๋ฆฌ์ฆ๋ ์ด์ํ ์ ์๋ค๋ฉด ๋๋จํ ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.
ํ์คํ ํ๋ก๋์ ์ค๋น๊ฐ ๋์ง ์์์ต๋๋ค. ์ฝ๋๋ ๋ณต์ฌ ํ์คํ, ๊ณต๊ฒฉ์ ์ธ ์ธ๋ผ์ธ ๋ฐ ์์ ํ์ง ์์ ์์ ํ์ฐ๊ณผ ๊ฐ์ ์์ฒญ๋ ์์ ๋ฌด์ฐจ๋ณ ๋์ ์ ์ ์ฉํฉ๋๋ค. ์๋์์ ์กด์ฌํ์ง ์์ผ๋ฉฐ ์ ๋ ฌ๋์ง ์์ ์ฝ๊ธฐ๋ ์์ต๋๋ค. ref-impl ํ ์คํธ ๋ฒกํฐ์ ๋ํ ํ ์คํธ์กฐ์ฐจ๋ ์๊ณกํ๊ฒ "๋ถ์์ "ํฉ๋๋ค.
๊ด์ฐฎ์. ์ฝ๋๋ฅผ ๊ฐ์ ธ์ค๊ธฐ๋ง ํ๋ฉด ํ์ํ ๊ฒฝ์ฐ ๋ค๋ฅธ ์ฌ๋์ด ์ฐพ์ ์ ์์ต๋๋ค.
์ด๊ฒ์ด ์กฐ๊ธ์ด๋ผ๋ ๋์์ด ๋๋ค๋ฉด ์์ผ๋ก 2์ฃผ ๋์ ๊ฐ์ฅ ์ฌ๊ฐํ ๋ฌธ์ ๋ฅผ ์์ ํ๊ณ ์ฝ๋์ ์ผ๋ถ ์๋น ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฉํ ์ ์๋ ์ถฉ๋ถํ ์๊ฐ์ ํ๋ณดํด์ผ ํฉ๋๋ค.
๊ทธ๋ ๊ทธ๊ฒ ์ข๊ฒ ๋ค!
@jamesqo ์๊ฒ ์ต๋๋ค . ๋ณด์ฌ๋๋ฆด ๊ฒ์ด ์์ผ๋ฉด ๋ฉ๋ชจํด
@gimpf ์ ๋ง ํ๋ฅญํ๊ฒ ๋ค๋ฆฌ๊ณ ์งํ ์ํฉ์ ๋ํด ๋ฃ๊ณ ์ถ์ต๋๋ค(๋ชจ๋ ์๊ณ ๋ฆฌ์ฆ์ ์๋ฃํ ๋๊น์ง ๊ธฐ๋ค๋ฆด ํ์๊ฐ ์์ต๋๋ค!). ์ฝ๋๊ฐ ์ฌ๋ฐ๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํ๊ณ ์ฑ๋ฅ์ด ํ๋ก๋์ ์ค๋น ๊ตฌํ์์ ๋ณผ ์ ์๋ ๊ฒ์ ์ ํํํ๋ค๊ณ ๋ฏฟ๋ ํ ํ๋ก๋์ ์ค๋น๊ฐ ๋์ง ์์๋ ๊ด์ฐฎ์ต๋๋ค. ํ๋ณด์๋ฅผ ์ ํํ๋ฉด ๊ณ ํ์ง ๊ตฌํ์ ์ํด ๊ทํ์ ํ๋ ฅํ ์ ์์ต๋๋ค.
seahash์ ์ํธ๋กํผ๊ฐ ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ๊ณผ ์ด๋ป๊ฒ ๋น๊ต๋๋์ง์ ๋ํ ๋ถ์์ ๋ณธ ์ ์ด ์์ต๋๋ค. ๊ทธ๊ฒ์ ๋ํ ํฌ์ธํฐ๊ฐ ์์ต๋๊น? ํฅ๋ฏธ๋ก์ด ์ฑ๋ฅ ์ ์ถฉ์์ด ์์ต๋๋ค... ๋ฒกํฐํ๋ ๋น ๋ฅด๊ฒ ๋ค๋ฆฌ์ง๋ง ๋ชจ๋์ ์ฐ์ ์ ๋๋ฆฌ๊ฒ ๋ค๋ฆฝ๋๋ค.
@morganbr ํฐ์ ์ค๋นํ์ต๋๋ค.
SeaHash ์๊ฐ : ์๋์, ํ์ง์ ๋ํด์๋ ์์ง ๋ชจ๋ฆ ๋๋ค. ์ฑ๋ฅ์ด ํฅ๋ฏธ๋ก์ด ๊ฒฝ์ฐ SMHasher์ ์ถ๊ฐํฉ๋๋ค. ์ ์ด๋ ์ ์๋ ๊ทธ๊ฒ์ด ์ข๋ค๊ณ ์ฃผ์ฅํ๊ณ (ํ์ผ ์์คํ ์ ์ฒดํฌ์ฌ์ ์ฌ์ฉ), ๋ํ ๋ฏน์ฑ ์ค์ ์ํธ๋กํผ๊ฐ ๋ฒ๋ ค์ง์ง ์๋๋ค๊ณ ์ฃผ์ฅํฉ๋๋ค.
ํด์ ๋ฐ ๋ฒค์น๋งํฌ ์ ๋ณด : ํ๋ก์ ํธ Haschisch.Kastriert , xx32, xx64, hsip13, hsip24, marvin32, sea ๋ฐ murmur3-32๋ฅผ ๋น๊ต ํ ์ฒซ ๋ฒ์งธ ๋ฒค์น๋งํน ๊ฒฐ๊ณผ๊ฐ ์๋ ์ํค ํ์ด์ง.
๋ช ๊ฐ์ง ์ค์ํ ์ฃผ์ ์ฌํญ:
์ฒซ์ธ์:
HashSet<>
์ ์ก์ธ์คํ๊ธฐ ์ํ "๋ฒค์น๋งํฌ"๋ ์์
์ด ํ์ํฉ๋๋ค. ๋ชจ๋ ๊ฒ์ด ๊ฑฐ์ ์ธก์ ์ค๋ฅ ๋ด์ ์๊ธฐ ๋๋ฌธ์
๋๋ค(๋ ํฐ ์ฐจ์ด๋ฅผ ๋ณด์์ง๋ง ์ฌ์ ํ ์ด์ผ๊ธฐํ ๊ฐ์น๊ฐ ์์)์ํฉ์ด ์กฐ๊ธ ๋์์ง๋ฉด ๋ค์ ๊ธ์ ์ฐ๊ฒ ์ต๋๋ค.
@gimpf , ํ์์ ์ธ ์์์ ๋๋ค! ์ฝ๋์ ๊ฒฐ๊ณผ๋ฅผ ์ดํด๋ณด๊ณ ๋ช ๊ฐ์ง ์ง๋ฌธ์ด ์์ต๋๋ค.
HashSet ๊ฒฐ๊ณผ๋ ํนํ ํฅ๋ฏธ๋กญ์ต๋๋ค. ๊ทธ๋ค์ด ์ ์งํ๋ค๋ฉด ๋ ๋น ๋ฅธ ํด์ ์๊ฐ๋ณด๋ค ๋ ๋์ ์ํธ๋กํผ๋ฅผ ์ ํธํ๋ ๊ฐ๋ฅํ ๊ฒฝ์ฐ์ ๋๋ค.
@morganbr ์ด๋ฒ ์ฃผ๋ง์ ๋ ๋ง์ด
๊ทํ์ ์ง๋ฌธ์ ๋ํด:
- ๊ฒฐ๊ณผ๋ SimpleMultiplyAdd๊ฐ @tannergooding ์ Murmur3a๋ณด๋ค ์ฝ 5๋ฐฐ ๋๋ฆฐ ๊ฒ์ผ๋ก ํ์๋ฉ๋๋ค. ์ด์ํด ๋ณด์ด๋๋ฐ...
๋๋ ๋ ์์ ์ด ๊ถ๊ธํ๋ค. ๊ทธ๊ฒ์ ๋ณต์ฌ/๋ถ์ฌ๋ฃ๊ธฐ ์ค๋ฅ์์ต๋๋ค. SimpleMultiplyAdd๋ ํญ์ 4๊ฐ์ ๊ฐ์ ๊ฒฐํฉํ์ต๋๋ค... ๋ํ ์ผ๋ถ ๋ช ๋ น๋ฌธ์ ์ฌ์ ๋ ฌํจ์ผ๋ก์จ ๊ณฑํ๊ธฐ-๋ํ๊ธฐ ๊ฒฐํฉ๊ธฐ๊ฐ ์ฝ๊ฐ ๋ ๋นจ๋ผ์ก์ต๋๋ค(~60% ๋ ๋์ ์ฒ๋ฆฌ๋).
๊ทํ์ ๊ตฌํ์ Murmur ๊ตฌํ์ ์๋ ์ผ๋ฐ์ ์ธ ๋นํจ์จ์ฑ์ด ์์ ์ ์์ต๋๊น? ์๋๋ฉด ์ด๊ฒ์ ๋ฒ์ฉ ๊ตฌํ๋ณด๋ค ํฐ ์ด์ ์ด ์๋ ์ฌ์ฉ์ ์ ์ ๊ตฌํ์ผ๋ก ์ฝ์ด์ผ ํฉ๋๊น?
๋ช ๊ฐ์ง๋ฅผ ๋์น ์ ์์ง๋ง .NET์ ๊ฒฝ์ฐ ์ด ์ฌ์ฉ ์ฌ๋ก์๋ ๋ฒ์ฉ ๊ตฌํ์ ์ฌ์ฉํ ์ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋๋ ๋ชจ๋ ์๊ณ ๋ฆฌ์ฆ์ ๋ํด Combine ์คํ์ผ ๋ฉ์๋๋ฅผ ์์ฑํ์ผ๋ฉฐ ๋๋ถ๋ถ์ wrt ํด์ ์ฝ๋ ๊ฒฐํฉ์ด ๋ฒ์ฉ ๋ฉ์๋๋ณด๋ค _ํจ์ฌ_ ๋ ์ ์ํ๋ฉ๋๋ค.
๊ทธ๋ฌ๋ ์ด๋ฌํ ๊ตฌํ์กฐ์ฐจ๋ ์ฌ์ ํ ๋๋ฌด ๋๋ฆฝ๋๋ค. ์ถ๊ฐ ์์ ์ด ํ์ํฉ๋๋ค. ์ด ์์ญ์ .NET ์ฑ๋ฅ์ ๋์๊ฒ ์ ๋์ ์ผ๋ก ๋ถํฌ๋ช ํฉ๋๋ค. ๋ก์ปฌ ๋ณ์์ ๋ณต์ฌ๋ณธ์ ์ถ๊ฐํ๊ฑฐ๋ ์ ๊ฑฐํ๋ฉด ์ฑ๋ฅ์ด 2๋ฐฐ ์ ๋ ์ฝ๊ฒ ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค. ์ต์์ ์ต์ ์ ์ ํํ๊ธฐ ์ํด ์ถฉ๋ถํ ์ ์ต์ ํ๋ ๊ตฌํ์ ์ ๊ณตํ ์ ์์ ๊ฒ์ ๋๋ค.
- 1, 2, 4 ์กฐํฉ์ ๋ํ ๊ฒฐ๊ณผ๊ฐ ์์ผ๋ฉด ์ข์ง๋ง ์ด API๋ 8๊น์ง ์ฌ๋ผ๊ฐ๋๋ค.
๊ฒฐํฉ ๋ฒค์น๋งํฌ๋ฅผ ํ์ฅํ์ต๋๋ค. ๊ทธ ์ ๋ฉด์ ๋๋ผ์์ด ์์ต๋๋ค.
- X64(...)์์ ์คํํ ๊ฒ์ ๋ณด์๋๋ฐ, X86 ๊ฒฐ๊ณผ๋ ์ฝ๊ฒ ์ป์ ์ ์๋์?
์์ ์๋ ๊ทธ๋ฌ์ง๋ง .NET Standard๋ก ์ด์ํ์ต๋๋ค. ์ด์ ์ ๋ ์ข ์์ฑ ์ง์ฅ์ ์์ผ๋ฉฐ .NET Core 2 ๋ฐ CLR 64๋นํธ ๋ฒค์น๋งํฌ๋ง ์๋ํฉ๋๋ค. ์ด๊ฒ์ ํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ฉด ์ถฉ๋ถํ ์ฝ๊ฒ ํด๊ฒฐํ ์ ์์ต๋๋ค.
์ด๊ฒ์ด v2.1 ๋ฆด๋ฆฌ์ค์์ ๊ฐ๋ฅํ๋ค๊ณ ์๊ฐํ์ญ๋๊น?
@gimpf ํ๋์ ๊ฒ์๋ฌผ์ ์ฌ๋ฆฌ์ง ์์ผ์ จ์ต๋๋ค. ๊ตฌํ์ ๋ํ ์งํ ์ํฉ ์ ๋ฐ์ดํธ๊ฐ ์์ต๋๊น? : ์ค๋ง์ผ :
@jamesqo ์ด์ํ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ๋ ๋ฒค์น๋งํฌ๋ฅผ ์์ ํ๊ณ ์ฌ์ฉ ๊ฐ๋ฅํ ์๊ณ ๋ฆฌ์ฆ ๋ชฉ๋ก์ City32, SpookyV2, Sip13 ๋ฐ Sip24๋ฅผ ์ถ๊ฐํ์ต๋๋ค. Sip์ ์์๋๋ก ๋น ๋ฅด๋ฉฐ(xx64์ ์ฒ๋ฆฌ๋์ ๋นํด) City์ Spooky๋ ๊ทธ๋ ์ง ์์ต๋๋ค(SeaHash์ ๊ฒฝ์ฐ์๋ ๋์ผ).
ํด์ ์ฝ๋๋ฅผ ๊ฒฐํฉํ๋ ๊ฒฝ์ฐ Murmur3-32๊ฐ ์ฌ์ ํ ์ข์ ์ ํ์ฒ๋ผ ๋ณด์ด์ง๋ง ์์ง ๋ ์ฒ ์ ํ ๋น๊ต๋ฅผ ์คํํ์ง ๋ชปํ์ต๋๋ค.
๋ ๋ค๋ฅธ ์ฐธ๊ณ ์ฌํญ์ผ๋ก ์คํธ๋ฆฌ๋ฐ API(.Add())๋ ํ๋ณด ๋ชฉ๋ก์์ ์ผ๋ถ ํด์ ์๊ณ ๋ฆฌ์ฆ์ ์ ๊ฑฐํ๋ ๋ถํํ ๋ถ์์ฉ์ด ์์ต๋๋ค. ๊ทธ๋ฌํ API์ ์ฑ๋ฅ๋ ์์ฌ์ค๋ฝ๋ค๋ ์ ์ ๊ฐ์ํ ๋ ์ฒ์๋ถํฐ ์ ๊ณตํ ์ง ์ฌ๋ถ๋ฅผ ๋ค์ ์๊ฐํด๋ณด๋ ๊ฒ์ด ์ข์ต๋๋ค.
.Add()
๋ถ๋ถ์ โโํผํ๊ณ ํด์ ๊ฒฐํฉ๊ธฐ๊ฐ ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ tg์ ๊ฒฐํฉ๊ธฐ๋ฅผ ์ ๋ฆฌํ๊ณ ์์ ํ
์คํธ ์ค์ํธ๋ฅผ ์์ฑํ๊ณ ์ ๊ทธ๋งํ๊ธฐ๋กํ๋ค. ์ฃผ๋ง๋ง๋ค ๋ช ์๊ฐ ๋ฐ์ ์ ํ๊ณ ์ฑ๋ฅ ์ต์ ํ๊ฐ ๋ค์ ์ง๋ฃจํ๊ธฐ ๋๋ฌธ์ ๊ธ๋๊ธ ๋ฒ์ ์ ๋ง๋๋ ๊ฒ์ ์ฝ๊ฐ ์ง๋ฃจํ ์ ์์ต๋๋ค ...
@gimpf , ๋๋จํ ์ง์ ์ฒ๋ผ ๋ค๋ฆฝ๋๋ค. ๊ฒฐ์ ์ ๋ด๋ฆฌ๊ณ ์์ผ๋ก ๋์๊ฐ ๋งํผ ์ถฉ๋ถํ์ง ํ์ธํ ์ ์๋๋ก ๊ฒฐ๊ณผ ํ ์ด๋ธ์ด ์์ต๋๊น?
@morganbr ๋ฒค์น๋งํน ๊ฒฐ๊ณผ๋ฅผ ์ ๋ฐ์ดํธํ์ต๋๋ค.
์ง๊ธ์ .NET Core 2์์ 64๋นํธ ๊ฒฐ๊ณผ๋ง ์ป์์ต๋๋ค. ํด๋น ํ๋ซํผ์ ๊ฒฝ์ฐ City64 w/o seed๊ฐ ๋ชจ๋ ํฌ๊ธฐ์์ ๊ฐ์ฅ ๋น ๋ฆ ๋๋ค. ์ข ์๋ฅผ ํตํฉํ์ฌ XX-32๋ Murmur-3-32์ ์ฐ๊ฒฐ๋ฉ๋๋ค. ์ด ์ข๊ฒ๋ ์ด๊ฒ๋ค์ 32๋นํธ ํ๋ซํผ์์ ๋น ๋ฅธ ๊ฒ์ผ๋ก ํํ์ด ์ข์ ๋์ผํ ์๊ณ ๋ฆฌ์ฆ์ด์ง๋ง ๋ถ๋ช ํ ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ด ์ ๊ตฌํ์๋ ์ ์ฉ๋๋์ง ํ์ธํด์ผ ํฉ๋๋ค. Sea์ SpookyV2๊ฐ ๋น์ ์์ ์ผ๋ก ๋๋ฆฐ ๊ฒ์ ์ ์ธํ๊ณ ๊ฒฐ๊ณผ๋ ์ค์ ์ฑ๋ฅ์ ๋ํ๋ด๋ ๊ฒ ๊ฐ์ต๋๋ค.
ํด์ ์ฝ๋ ๊ฒฐํฉ๊ธฐ์ ๋ํ ํด์ ๋์ค ๋ณดํธ๊ฐ ์ผ๋ง๋ ํ์ํ์ง ๊ณ ๋ คํด์ผ ํฉ๋๋ค. ์๋๊ฐ ํด์๋ฅผ ์ง์์ฑ์ ์ํด ๋ถ๋ช ํ ์ฌ์ฉํ ์ ์๋๋ก ๋ง๋๋ ๋ฐ๋ง ํ์ํ ๊ฒฝ์ฐ 32๋นํธ ์๋๋ก XORํ๋ฉด city64๊ฐ ๊ฐ์ ๋ ๊ฒ์ ๋๋ค. ์ด ์ ํธ๋ฆฌํฐ๋ ํด์๋ฅผ ๊ฒฐํฉํ๊ธฐ ์ํด์๋ง ์กด์ฌํ๋ฏ๋ก(์๋ฅผ ๋ค์ด ๋ฌธ์์ด์ ํด์ ์ฝ๋๋ฅผ ๋์ฒดํ๊ฑฐ๋ ์ ์ ๋ฐฐ์ด ๋ฑ์ ๋๋กญ์ธ ํด์๊ฐ ๋์ง ์์) ์ถฉ๋ถํ ์ ์์ต๋๋ค.
OTOH๊ฐ ํ์ํ๋ค๊ณ ์๊ฐํ๋ค๋ฉด Sip13์ด ์ผ๋ฐ์ ์ผ๋ก XX-32(64๋นํธ ํ๋ซํผ์์)๋ณด๋ค 50% ๋ฏธ๋ง ๋๋ฆฌ๋ค๋ ๊ฒ์ ์๊ฒ ๋์ด ๊ธฐ์ฉ๋๋ค. ๊ทธ๋ฌ๋ ๊ทธ ๊ฒฐ๊ณผ๋ 32๋นํธ ์ฑ์์ ํฌ๊ฒ ๋ค๋ฅผ ์ ์์ต๋๋ค.
corefx์ ์ผ๋ง๋ ๊ด๋ จ์ด ์๋์ง ๋ชจ๋ฅด์ง๋ง LegacyJit 32๋นํธ(w/FW 4.7) ๊ฒฐ๊ณผ๋ฅผ ์ถ๊ฐํ์ต๋๋ค.
๊ฒฐ๊ณผ๊ฐ ํฐ๋ฌด๋์์ด ๋๋ฆฌ๋ค๊ณ ๋งํ๊ณ ์ถ์ต๋๋ค. ๊ทธ๋ฌ๋ ์๋ฅผ ๋ค์ด, 56 MiB/s ๋ 319 MiB/s์์ ๋๋ ์์ง ์์ต๋๋ค(์ฆ, Sip, ์ผ์ชฝ ํ์ ์ต์ ํ๊ฐ ๊ฐ์ฅ ๋๋ฝ๋จ). 1์์ .NET ํด์ ์๊ณ ๋ฆฌ์ฆ ํ๋ก์ ํธ๋ฅผ ์ทจ์ํ ์ด์ ๋ฅผ ๊ธฐ์ตํฉ๋๋ค...
๋ฐ๋ผ์ RyuJit-32bit๋ ์ฌ์ ํ ๋๋ฝ๋์์ผ๋ฉฐ (๋ฐ๋ผ๊ฑด๋) ๋งค์ฐ ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํ ๊ฒ์ด์ง๋ง LegacyJit-x86์ ๊ฒฝ์ฐ Murmur-3-32๊ฐ ์ฝ๊ฒ ์น๋ฆฌํ๊ณ City-32์ xx-32๋ง ๊ทผ์ ํ ์ ์์ต๋๋ค. Murmur๋ ์ฌ์ ํ 0.6~2GB/s๊ฐ ์๋ ์ฝ 0.4~1.1GB/s๋ก ์ฑ๋ฅ์ด ์ข์ง ์์ง๋ง(๋์ผํ ์์คํ ์์), ์ ์ด๋ ์ ์ ํ ์์ค์ ์์ต๋๋ค.
์ค๋ ๋ฐค ๋ช ๋์ ์ ํ์ ๋ํด ๋ฒค์น๋งํฌ๋ฅผ ์คํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๊ฒ์ํ ์์ ์ ๋๋ค(Ryzen, i7, Xeon, A10, i7 Mobile ๋ฐ ๊ธฐํ ๋ช ๊ฐ์ง).
@tannergooding @morganbr ๋ช ๊ฐ์ง ํ๋ฅญํ๊ณ ์ค์ํ ์ ๋ฐ์ดํธ์ ๋๋ค.
์ค์ํ ์ฒซ ๋ฒ์งธ:
์ข์ ๊ฒ๋ค:
"Empty"(์์ ์ค๋ฒํค๋) ๋ฐ "multiply-add"(์ ๋ช ํ SO ๋ต๋ณ์ ์๋ ์ต์ ํ ๋ฒ์ )๋ฅผ ํฌํจํ์ฌ ํด์ ์ฝ๋๋ฅผ ๊ฒฐํฉํ๊ธฐ ์ํ ๋ชจ๋ ์ฃผ์ ๊ตฌํ์์ ์ ํ๊ตฐ์ ์คํํ๋ ค๋ฉด:
bin\Release\net47\Haschisch.Benchmarks.Net47.exe -j:clr_x86 -j:clr_x64_legacy -j:clr_x64 -j:core_x64 -- CombineHashCode --allcategories=prime
(_32๋นํธ ์ฝ์ด ๋ฒค์น๋งํฌ๋ฅผ ํธ๋ฆฌํ๊ฒ ์คํํ๋ ค๋ฉด ์ํํ BenchmarkDotNet(๋๋ ์ฝ์ด ๊ธฐ๋ฐ ๋ฒค์น ๋ฌ๋๋ฅผ ์ฌ์ฉํ๋ 32๋นํธ ์ ์ฉ ์ค์ ํ๋ฌ์ค)์ด ํ์ํ ๊ฒ ๊ฐ์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ -j:core_x86์ ์ฌ์ฉํ์ฌ ์๋ํด์ผ ํฉ๋๋ค.
๊ฒฐ๊ณผ : ๋ชจ๋ ๋ฒ๊ทธ ์์ ํ "๋น ๋ฅธ" ์คํ์์ ๋ชจ๋ฐ์ผ Haswell i7์ Windows 10์์ xx32๊ฐ 64๋นํธ RyuJIT๋ฅผ ํฌํจํ๋ ๋ชจ๋ ์ค๋ฒ๋ก๋์ ๋ํด ์น๋ฆฌํ ๊ฒ ๊ฐ์ต๋๋ค. Sips์ marvin32 ์ฌ์ด์์ Sip-1-3์ด ํญ์ ์ด๊น๋๋ค. Sip-1-3์ xx32๋ณด๋ค ์ฝ 4๋ฐฐ ๋๋ฆฌ๋ฉฐ, ์ด๋ ๋ค์ ๊ธฐ๋ณธ ๊ณฑ์ -๋ง์ ๊ฒฐํฉ๊ธฐ๋ณด๋ค ์ฝ 2๋ฐฐ ๋๋ฆฝ๋๋ค. 32๋นํธ ์ฝ์ด ๊ฒฐ๊ณผ๋ ์ฌ์ ํ ๋๋ฝ๋์์ง๋ง ํด๋น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ์ค ์์ ์ ์ธ BenchmarkDotNet ๋ฆด๋ฆฌ์ค๋ฅผ ์ด๋ ์ ๋ ๊ธฐ๋ค๋ฆฌ๊ณ ์์ต๋๋ค.
(ํธ์ง) ๋ฐฉ๊ธ ํด์ ์ธํธ์ ์ก์ธ์คํ๊ธฐ ์ํ ๋ฒค์น๋งํฌ ์ ๋น ๋ฅธ ์คํ์ ์ถ๊ฐํ์ต๋๋ค. ์ด๊ฒ์ ๋ถ๋ช ํ ์์ ยต-๋ฒค์น๋งํฌ๋ณด๋ค ์ธ๋ถ ์ฌํญ์ ํจ์ฌ ๋ ์์กดํ์ง๋ง ํ ๋ฒ ์ดํด๋ณด๊ณ ์ถ์ ์๋ ์์ต๋๋ค.
ํ์์ ์ธ ๋ฐ์ดํฐ์ ๋ํด @gimpf ์๊ฒ ๋ค์ ํ ๋ฒ ๊ฐ์ฌ๋๋ฆฝ๋๋ค! ์ฐ๋ฆฌ๊ฐ ๊ทธ๊ฒ์ ๊ฒฐ์ ์ผ๋ก ๋ฐ๊ฟ ์ ์๋์ง ๋ด ์๋ค.
์ฐ์ ์๊ณ ๋ฆฌ์ฆ์ ๋ค์๊ณผ ๊ฐ์ด ๋๋๋๋ค.
Fast+Good ์ํธ๋กํผ(์๋์):
HashDoS ๋ด์ฑ:
๊ฒฝํฉ ์์(๋๋ฆผ):
๊ฒฝํฉ ์์(๋์ ์ํธ๋กํผ):
์ฐ์น์๋ฅผ ์ ํํ๊ธฐ ์ ์ ๋ค๋ฅธ ์ฌ๋๋ค์ด ์์ ๋ฒํท์ ๋์ํ๋์ง ํ์ธํ๊ณ ์ถ์ต๋๋ค. ๊ทธ๊ฒ์ด ์ ์ง๋๋ค๋ฉด ์ฐ๋ฆฌ๋ HashDoS ์ ํญ์ ๋ํด 2๋ฐฐ๋ฅผ ์ง๋ถํ ์ง ์ฌ๋ถ๋ฅผ ์ ํํ ๋ค์ ์๋์ ๋ฐ๋ผ ๊ฐ์ผํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
@morganbr ๊ทธ๋ฃนํ๊ฐ ์ ๋ ๊ฒ ๊ฐ์ต๋๋ค. SipHash ๋ผ์ด๋์ ๋ฐ์ดํฐ ํฌ์ธํธ๋ก์ Rust ํ๋ก์ ํธ๋ sip-hash w/DJB๋ฅผ ์์ฑํ Jean-Philippe Aumasson ์๊ฒ ์ง๋ฌธํ์ต๋๋ค. ๊ทธ ๋ ผ์ ํ์ ๊ทธ๋ค์ ํด์ ํ ์ด๋ธ์ ๋ํด sip-1-3์ ์ฌ์ฉํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
( PR rust:#33940 ๋ฐ ํจ๊ป ์ ๊ณต๋๋ ๋ฌธ์ rust:#29754 ์ฐธ์กฐ ).
๋ฐ์ดํฐ์ ์๊ฒฌ์ ๋ฐํ์ผ๋ก ๋ชจ๋ ์ํคํ ์ฒ์์ xxHash32 ๋ฅผ ์ฌ์ฉํ ๊ฒ์ ์ ์ํ๊ณ ์ถ์ต๋๋ค. ๋ค์ ๋จ๊ณ๋ ๊ตฌํํ๋ ๊ฒ์ ๋๋ค. @gimpf , ์ด์ ๋ํ PR์ ๊ตฌ์ฑํ๋ ๋ฐ ๊ด์ฌ์ด ์์ต๋๊น?
HashDoS์ ๋ํด ์ฐ๋ คํ๋ ๋ถ๋ค์ ์ํด Marvin32๋ฅผ ํฌํจํด์ผ ํ๊ณ SipHash๋ฅผ ํฌํจํ ์ ์๋ ๋ฒ์ฉ ํด์ฑ API์ ๋ํ ์ ์์ ๊ณง ์ด์ด๊ฐ ๊ฒ์ ๋๋ค. ๊ทธ๊ฒ์ ๋ํ @gimpf ์ @tannergooding ์ด ์์ ํ ๋ค๋ฅธ ๊ตฌํ์ ์ํ ์ ์ ํ ์ฅ์๊ฐ ๋ ๊ฒ์ ๋๋ค.
@morganbr ์๊ฐ์ด ํ๋ฝํ๋ ํ PR์ ํ ์ ์์ต๋๋ค. ๋ํ ๊ฐ์ธ์ ์ผ๋ก xx32๋ ์์ฉ์ ์ค์ด์ง ์๋ ํ ์ ํธํฉ๋๋ค.
@gimpf , ์๊ฐ์ด ์ด๋ป๊ฒ
@morganbr 11์ 5์ผ๊น์ง ํ๊ธฐ๋ก ๊ณํํ๋๋ฐ ์์ผ๋ก 2์ฃผ ์์ ์๊ฐ์ ์ฐพ์ ์ ์์ด ์ฌ์ ํ ์ข์ ๋ณด์ ๋๋ค.
@gimpf , ์ ๋ค๋ฆฝ๋๋ค. ์ ๋ฐ์ดํธํด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
@terrajobst - ํํฐ์ ์ข ๋ฆ์์ง๋ง(์ฃ์กํฉ๋๋ค.) Add ๋ฉ์๋์ ๋ฐํ ์ ํ์ ๋ณ๊ฒฝํ ์ ์๋์?
```c#
๊ณต๊ฐ ํด์์ฝ๋ ์ถ๊ฐ
๊ณต๊ฐ ํด์์ฝ๋ ์ถ๊ฐ
The params code is clearly there for scenarios where you have multiple fields, e.g.
```c#
public override int GetHashCode() => new HashCode().Add(Name, Surname).ToHashCode();
๊ทธ๋ฌ๋ ํ๋์ ๋ ๋ญ๋น์ ์ธ ๋ฐฐ์ด ํ ๋น์๋ ๋ถ๊ตฌํ๊ณ ๋ค์๊ณผ ๊ฐ์ด ์ ํํ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
c#
public override int GetHashCode() => new HashCode().Add(Name).Add(Surname).Add(Age).ToHashCode();
์ ํ์ ํผํฉํ ์๋ ์์ต๋๋ค. ์ด๊ฒ์ ๋ถ๋ช
ํ ์ผ๋ฐ ๋ฉ์๋ ๋ด์์ ์ ์ฐฝํ๊ฒ ํธ์ถ ํ์ง ์์ ์ผ๋ก์จ ์ํ๋ ์ ์์ต๋๋ค. ์ ์ฐฝํ ์ธํฐํ์ด์ค๊ฐ ์ ๋์ ์ผ๋ก ํ์ํ์ง ์๋ค๋ ์ด ์ฃผ์ฅ์ ๊ฐ์ํ ๋ ์ฒ์์๋ ๋ญ๋น์ ์ธ params
์ค๋ฒ๋ก๋๊ฐ ์กด์ฌํ๋ ์ด์ ๋ ๋ฌด์์
๋๊น? ์ด ์ ์์ด ์๋ชป๋ ์ ์์ด๋ผ๋ฉด params
์ค๋ฒ๋ก๋๋ ๋์ผํ ์ถ์ผ๋ก ๋จ์ด์ง๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ฌ์ํ์ง๋ง ์ต์ ์ ํด์์ฝ๋์ ๋ํ ์ ๊ท์ ์ธ ๋ฐฉ๋ฒ์ ๊ฐ์ํ๋ ๊ฒ์ ๋ง์ ์์์ฒ๋ผ ๋ณด์
๋๋ค.
ํธ์ง: implicit operator int
๋ DRY์๋ ์ข์ง๋ง ์ ํํ ์ค์ํ์ง๋ ์์ต๋๋ค.
@jcdickinson
Add ๋ฉ์๋์ ๋ฐํ ์ ํ์ ๋ณ๊ฒฝํ ์ ์์ต๋๊น?
์ฐ๋ฆฌ๋ ์ด๋ฏธ ์ด์ ์ ์์์ ๋ ผ์ํ์ง๋ง ๊ฑฐ๋ถ๋์์ต๋๋ค.
๋ญ๋น์ ์ธ params ๊ณผ๋ถํ๊ฐ ์ฒ์์ ์กด์ฌํ๋ ์ด์ ๋ ๋ฌด์์ ๋๊น?
params ์ค๋ฒ๋ก๋๋ฅผ ์ถ๊ฐํ์ง ์์ต๋๊น? ์ด ์น ํ์ด์ง์์ "params"์ ๋ํด Ctrl+F๋ฅผ ์ํํ๋ฉด ํด๋น ๋จ์ด๊ฐ ํ์๋๋ ์ ์ผํ ์์น์ ๊ทํ์ ๋๊ธ์ด ์์์ ์ ์ ์์ต๋๋ค.
์์์ ์ฐ์ฐ์ int๋ DRY์ ์ ํฉํ์ง๋ง ์ ํํ ์ค์ํ์ง๋ ์์ต๋๋ค.
์์ ์ด๋๊ฐ์์ ๋ ผ์ ๋ ๊ฒ ๊ฐ์ต๋๋ค ...
@jamesqo ์ค๋ช ๊ฐ์ฌํฉ๋๋ค.
๋งค๊ฐ๋ณ์ ์ค๋ฒ๋ก๋
๋๋ AddRange
์๋ฏธํ์ง๋ง, ๋๋ ์ด๊ฒ์ ๋ํด ์ด๋ค ๊ฒฌ์ธ๋ ฅ๋ ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
@jcdickinson AddRange
์ ์๋ ์ ์์์ ์์์ง๋ง ํ์ฌ ๋ฒ์ ์๋ ์์ต๋๋ค. API ๊ฒํ ์์ ๊ฑฐ๋ถ๋์์ต๋๋ค(@terrajobst์ https://github.com/dotnet/corefx/issues/14354#issuecomment-308190321 ์ฐธ์กฐ).
์๋๋ฆฌ์ค๊ฐ ๋ถ๋ถ๋ช ํ๊ธฐ ๋๋ฌธ์ ๋ชจ๋
AddRange
๋ฉ์๋๋ฅผ ์ ๊ฑฐํด์ผ ํฉ๋๋ค. ๋ฐฐ์ด์ ๋งค์ฐ ์์ฃผ ํ์๋ ๊ฐ๋ฅ์ฑ์ด ๋ค์ ๋ฎ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ผ๋จ ๋ ํฐ ๋ฐฐ์ด์ด ๊ด๋ จ๋๋ฉด ๋ฌธ์ ๋ ๊ณ์ฐ์ ์บ์ํด์ผ ํ๋์ง ์ฌ๋ถ์ ๋๋ค. ํธ์ถ ์ธก์์ for ๋ฃจํ๋ฅผ ๋ณด๋ฉด ๊ทธ๊ฒ์ ๋ํด ์๊ฐํ ํ์๊ฐ ์์์ ๋ถ๋ช ํ ์ ์ ์์ต๋๋ค.
@gimpf xxHash32๋ก ์ ์์๋ฅผ ํด๋ฆฌํํ์ต๋๋ค . ๊ทธ ๊ตฌํ์ ์์ ๋กญ๊ฒ ์ก์ผ์ญ์์ค. ์ค์ xxHash32 ๋ฒกํฐ์ ๋ํ ํ ์คํธ๊ฐ ์์ต๋๋ค.
์ธํฐํ์ด์ค์ ๊ดํด์. ๋๋ ๋ด๊ฐ ๋๋์ง ์ธ๋์์ ์ฐ์ ๋ง๋ค๊ณ ์๋ค๋ ๊ฒ์ ์์ ํ ์๊ณ ์์ต๋๋ค. ๋ฌด์ํ์ ๋ ๋ฉ๋๋ค. ๋๋ ์ค์ ๋ฌผ๊ฑด์ ๋ํด ํ์ฌ ์ ์์ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ ์ง์ฆ๋๋ ๋ฐ๋ณต์ด ๋ง์ต๋๋ค.
๋๋ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง๊ณ ๋์๊ณ ์ด์ ์ ์ฐฝํ ์ธํฐํ์ด์ค๊ฐ ๊ฑฐ๋ถ๋ ์ด์ ๋ฅผ ์ดํดํฉ๋๋ค. ์๋นํ ๋๋ฆฝ๋๋ค.
BenchmarkDotNet=v0.10.9, OS=Windows 10 Redstone 2 (10.0.15063)
Processor=Intel Core i7-4800MQ CPU 2.70GHz (Haswell), ProcessorCount=8
Frequency=2630626 Hz, Resolution=380.1377 ns, Timer=TSC
.NET Core SDK=2.0.2
[Host] : .NET Core 2.0.0 (Framework 4.6.00001.0), 64bit RyuJIT
DefaultJob : .NET Core 2.0.0 (Framework 4.6.00001.0), 64bit RyuJIT
์ธ๋ผ์ธ๋์ง ์์ ๋ฉ์๋๋ฅผ ํด์ ์ฝ๋ ์์ค๋ก ์ฌ์ฉ Add์ 50ํ ํธ์ถ๊ณผ ์ ์ฐฝํ ํ์ฅ ๋ฐฉ๋ฒ:
| ๋ฐฉ๋ฒ | ํ๊ท | ์ค๋ฅ | ํ์ค ๊ฐ๋ฐ | ์ค์ผ์ผ |
|--------- |---------:|---------:|---------:|---------: |
| ์ถ๊ฐ | 401.6ns | 1.262ns | 1.180ns | 1.00 |
| ํ๋ฆฌ | 747.8ns | 2.329ns | 2.178ns | 1.86 |
๊ทธ๋ฌ๋ ๋ค์ ํจํด์ด ์๋ํฉ๋๋ค.
```c#
๊ณต๊ฐ ๊ตฌ์กฐ์ฒด HashCode : System.Collections.IEnumerable
{
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("์ด ๋ฉ์๋๋ ์ปฌ๋ ์
์ด๋์
๋ผ์ด์ ๊ตฌ๋ฌธ์ ์ ๊ณต๋ฉ๋๋ค.", ์ค๋ฅ: true)]
public IEnumerator GetEnumerator() => ์๋ก์ด NotImplementedException() ๋์ง๊ธฐ;
}
public override int GetHashCode() => new HashCode()
{
Age, // int
{ Name, StringComparer.Ordinal }, // use Comparer
Hat // some arbitrary object
}.ToHashCode();
```
๋ํ ํ์ฌ ์ ์๊ณผ ๋์ผํ ์ฑ๋ฅ ํน์ฑ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
| ๋ฐฉ๋ฒ | ํ๊ท | ์ค๋ฅ | ํ์ค ๊ฐ๋ฐ | ์ค์ผ์ผ |
|------------ |---------:|---------:|---------:|--- ----:|
| ์ถ๊ฐ | 405.0ns | 2.130ns | 1.889ns | 1.00 |
| ์ด๊ธฐํ | 400.8ns | 4.821ns | 4.274ns | 0.99 |
์ฌํ๊ฒ๋ IEnumerable
๋ ์ปดํ์ผ๋ฌ๋ฅผ ๋ง์กฑ์ค๋ฝ๊ฒ ์ ์งํ๊ธฐ ์ํด ๊ตฌํ๋์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ค์ ํดํน์
๋๋ค. ์ฆ, Obsolete
๋ foreach
์์๋ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ๋ ค๋ฉด ์ค์ ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ผ ํฉ๋๋ค. ๋์ MSIL์ ๋ณธ์ง์ ์ผ๋ก ๋์ผํฉ๋๋ค.
@jcdickinson ๋ฌธ์ ๋ฅผ ์ก์์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. Collaborator ์ด๋๋ฅผ ๋ณด๋์ต๋๋ค. ์๋ฝํ ๋ ์๋ ค์ฃผ์ญ์์ค. ๊ทธ๋ฌ๋ฉด ์ด ๋ฌธ์ ๋ฅผ ๊ทํ์๊ฒ ํ ๋นํ ์ ์์ต๋๋ค(๊ทธ ๋์ ๋ ์์ ์๊ฒ ํ ๋น).
์ ๋ฌธ๊ฐ ํ: ์๋ฝํ๋ฉด GitHub์์ ์ ์ฅ์์ ๋ชจ๋ ์๋ฆผ(ํ๋ฃจ 500๊ฐ ์ด์)์ ๋ํด ์๋์ผ๋ก ๋ฑ๋กํฉ๋๋ค. ๋ฌธ์ ์ ๋ํ ๋ชจ๋ ๋ฉ์ ๋ฐ ์๋ฆผ์ ๋ณด๋ด๋ "Not Watching"์ผ๋ก ๋ณ๊ฒฝํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ๊ตฌ๋ ํ์ต๋๋ค.
@jcdickinson , ๋๋ ์ฑ๊ฐ์ ๋ฐ๋ณต์ ํผํ๋ ๋ฐฉ๋ฒ์ ํ์คํ ๊ด์ฌ์ด ์์ต๋๋ค(์ด๊ธฐํ ๊ตฌ๋ฌธ์ ๋ํด ์ฌ๋๋ค์ด ์ด๋ป๊ฒ ๋๋์ง๋ ๋ชจ๋ฅด์ง๋ง). ๋๋ ์ ์ฐฝํจ์ ๋ ๊ฐ์ง ๋ฌธ์ ๊ฐ ์์๋ค๋ ๊ฒ์ ๊ธฐ์ตํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
var hc = new HashCode();
var newHc = hc.Add(foo);
hc.Add(bar);
return newHc.ToHashCode();
์ด ์ค๋ ๋์ ์ ์์ ์ด๋ฏธ ์น์ธ๋์์ผ๋ฉฐ(๊ทธ๋ฆฌ๊ณ ๋ณํฉํ๋ ๋ฐ ์์กฐ๋กญ์ต๋๋ค), ๋ณ๊ฒฝ ์ฌํญ์ ๋ํด ์ API ์ ์์ ์์ํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
@karelz ๋๋ @gimpf๊ฐ ์ด๋ฏธ ์ด ๋ฌธ์ ๋ฅผ ๋ฏธ๋ฆฌ @gimpf์ ๋์ ํ ๋นํ์ญ์์ค. ( ํธ์ง: nvm)
@terrajobst ์ด์ ๋ํ ์ผ์ข
์ ๋งํ API ์์ฒญ์
๋๋ค. GetHashCode
์ฌ์ฉํ์ง ์์์ผ๋ก ํ์ํ๊ธฐ ๋๋ฌธ์ HashCode
๋ ์ผ๋ฐ์ ์ผ๋ก ๋ณ๊ฒฝ ๋ถ๊ฐ๋ฅ/๋น๊ตํ ์ ์๋ ๊ตฌ์กฐ์ฒด์์๋ ๋ถ๊ตฌํ๊ณ ๋น๊ต ๋์์ด ์๋๋ผ๋ ๊ฒ์ ์์์ ์ผ๋ก ์ฌ์ฉ์์๊ฒ ์๋ฆฝ๋๋ค. ์ด ๊ฒฝ์ฐ Equals
์ฌ์ฉ๋์ง ์๋ ๊ฒ์ผ๋ก ํ์ํด์ผ ํฉ๋๊น?
[Obsolete("HashCode is a mutable struct and should not be compared with other HashCodes.", error: true)]
[EditorBrowsable(Never)]
// If this is too harsh, base.Equals() is fine as long as the [Obsolete] stays
public override bool Equals(object obj) => throw new NotSupportedException("HashCode is a mutable struct and should not be compared with other HashCodes.");
๋น์ทํ ๊ฒ์ด Span
๋ก ์ํ๋์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๊ทธ๊ฒ ๋ฐ์๋ค์ฌ์ง๋ค๋ฉด...
cannot
๋์ should not
๋๋ may not
์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.@Joe4evr ์ ์ ์ GetHashCode
์์ธ์๋ ๋์ผํ ๋ฉ์์ง๋ฅผ ํฌํจํ๋ ๊ฒ์ด ๋์์ด ๋ ์ ์์ต๋๋ค.
public override int GetHashCode() => throw new NotSupportedException("HashCode is a mutable struct and should not be compared with other HashCodes.");
@morganbr ์ ์ด๊ฒ์ ๋ค์
CoreFX์ ๋ ธ์ถ์ํค๊ธฐ ์ํ PR์ ์์ง ์งํ๋์ง ์์์ต๋๋ค.
@gimpf ๋ฒค์น๋งํนํ ์ฝ๋๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๊น? ๋๋ SpookilySharp nuget ํจํค์ง๊ฐ ์ด๋ป๊ฒ ์๋ํ๋์ง ๋น ๋ฅด๊ฒ ํ์ธํ ์ ์์ต๋๊น? ๋๋ 2๋ ์ ์นจ์ฒด ์ดํ์ ๊ทธ ํ๋ก์ ํธ์ ๋จผ์ง๋ฅผ ํธ์ด๋ด๋ ค ํ๊ณ ์๊ณ ๊ทธ๊ฒ์ด ์ด๋ป๊ฒ ์ ์๋์ง ๊ถ๊ธํฉ๋๋ค.
@JonHanna ๊ทธ๋ ์ฌ๊ธฐ์ ๊ฒ์ํ์ต๋๋ค: https://github.com/gimpf/Haschisch.Kastriert
@JonHanna , ๋ฒ์ฉ ๋น์ํธํ ํด์ฑ API์์ ๋ฌด์์ด ์ ์ฉํ์ง ์๊ฐํ ์ ์๋๋ก ํ ์คํธ๊ฐ ์ด๋ป๊ฒ ์งํ๋๋์ง ๋ฃ๊ณ ์ถ์ต๋๋ค.
@morganbr ๊ทธ๋ฌํ API๋ฅผ ๋ ผ์ํ ์ ์ ํ ํฌ๋ผ์ ์ด๋์ธ๊ฐ์? ๋๋ ๊ทธ๋ฌํ API๊ฐ ๊ฐ์ฅ ๋ฎ์ ๊ณตํต ๋ถ๋ชจ ์ด์์ผ๋ก ๊ตฌ์ฑ๋ ๊ฒ์ผ๋ก ์์ํ๋ฉฐ, ์๋ง๋ ์ข์ API๋ ๋ ํฐ ๊ตฌ์กฐ์ฒด์ ํฅ์๋ JIT wrt ์ฒ๋ฆฌ๋ ํ์๋ก ํ ๊ฒ์ ๋๋ค. ๋ณ๋์ ๋ฌธ์ ์์ ๋ ์ ์ํํ ์ ์๋ ๋ชจ๋ ๊ฒ์ ๋ํด ๋ ผ์...
@gimpf ๋น์ ์ ์ํด ํ๋๋ฅผ ์ด์์ต๋๋ค. ๋ท๋ท/corefx#25666
@morganbr - ์ด ์ปค๋ฐ์ ํฌํจํ ํจํค์ง ์ด๋ฆ ๋ฐ ๋ฒ์ ๋ฒํธ๋ฅผ ์ป์ ์ ์์ต๋๊น?
@karelz , ํจํค์ง/๋ฒ์ ์ ๋ณด๋ก @smitpatel ์ ๋์ธ ์ ์์ต๋๊น?
๋๋ .NET Core์ ๋งค์ผ ๋น๋๋ฅผ ์๋ํ ๊ฒ์
๋๋ค - ๋๋ ๋ด์ผ๊น์ง ๊ธฐ๋ค๋ฆด ๊ฒ์
๋๋ค.
๋๋ ๋น์ ์ด ๋จ์ํ ์์กดํ ์ ์๋ ํจํค์ง๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ฌ๊ธฐ ์ฐธ๊ฐ์๋ค์๊ฒ ์ง๋ฌธํฉ๋๋ค. Roslyn IDE๋ฅผ ์ฌ์ฉํ๋ฉด ํด๋์ค/๊ตฌ์กฐ์ฒด์ ํ๋/์์ฑ ์งํฉ์ ๊ธฐ๋ฐ์ผ๋ก GetHashCode impl์ ์์ฑํ ์ ์์ต๋๋ค. ์ด์์ ์ผ๋ก ์ฌ๋๋ค์ https://github.com/dotnet/corefx/pull/25013 ์ ์ถ๊ฐ๋ ์๋ก์ด HashCode.Combine์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ผ๋ถ ์ฌ์ฉ์๋ ํด๋น ์ฝ๋์ ์ก์ธ์คํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ ์ฌ์ ํ ๊ทธ๋ค์๊ฒ ์๋ํ GetHashCode๋ฅผ ์์ฑํ ์ ์๊ธฐ๋ฅผ ์ํฉ๋๋ค.
์ต๊ทผ์ ์ฐ๋ฆฌ๊ฐ ์์ฑํ๋ ํ์์ด ๋ฌธ์ ๊ฐ ์๋ค๋ ์ฌ์ค์ด ์๋ ค์ก์ต๋๋ค. ์ฆ, VB๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ค๋ฒํ๋ก ๊ฒ์ฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ปดํ์ผํ๊ณ impl์ ์ค๋ฒํ๋ก๋ฅผ ๋ฐ์์ํต๋๋ค. ๋ํ VB๋ ์ฝ๋ ์์ญ์ ๋ํ ์ค๋ฒํ๋ก ๊ฒ์ฌ๋ฅผ ๋นํ์ฑํํ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ์ ์ฒด ์ด์ ๋ธ๋ฆฌ์ ๋ํด ์์ ํ ์ผ์ ธ ์๊ฑฐ๋ ๊บผ์ ธ ์์ต๋๋ค.
์ด ๋๋ฌธ์ ์ฐ๋ฆฌ๊ฐ ์ ๊ณตํ๋ impl์ ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ๊ฒช์ง ์๋ ํ์์ผ๋ก ๋์ฒดํ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ์ด์์ ์ผ๋ก ์์ฑ๋ ์์์๋ ๋ค์๊ณผ ๊ฐ์ ์์ฑ์ด ์์ต๋๋ค.
a + b + c + d
๋๋ a ^ b ^ c ^ d
์ผ๋ฐ์ ์ผ๋ก ๋ฐ์ํ๋ ๋ฌธ์ ๊ฐ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.์๋ฅผ ๋ค์ด, VB์ ๋ํ ํ ๊ฐ์ง ์ต์ ์ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ ์์ฑํ๋ ๊ฒ์ ๋๋ค.
return (a, b, c, d).GetHashCode()
๊ทธ๋ฌ๋ ์ด๊ฒ์ System.ValueTuple์ ๋ํ ์ฐธ์กฐ๊ฐ ์๋์ง์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค. ์ด์์ ์ผ๋ก๋ ๊ทธ๊ฒ์ด ์์ด๋ ์๋ํ๋ impl์ ๊ฐ์ง ์ ์์ต๋๋ค.
๋๊ตฌ๋ ์ง ์ด๋ฌํ ์ ์ฝ ์กฐ๊ฑด๊ณผ ํจ๊ป ์๋ํ ์ ์๋ ์ ์ ํ ํด์ฑ ์๊ณ ๋ฆฌ์ฆ์ ๋ํด ์๊ณ ์์ต๋๊น? ๊ฐ์ฌ ํด์!
--
์ฐธ๊ณ : ๊ธฐ์กด์ ๋ด๋ณด๋ธ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Dim hashCode = -252780983
hashCode = hashCode * -1521134295 + i.GetHashCode()
hashCode = hashCode * -1521134295 + j.GetHashCode()
Return hashCode
์ด๊ฒ์ ๋ถ๋ช ํ ๋์น ์ ์์ต๋๋ค.
์ด ์ฝ๋ ์ฃผ์์ unchecked { }
์ถ๊ฐํ ์ ์์ผ๋ฏ๋ก C#์ ๊ฒฝ์ฐ์๋ ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค. VB์์๋ ์ธ๋ฐํ ์ ์ด๊ฐ ๋ถ๊ฐ๋ฅํฉ๋๋ค.
๋๊ตฌ๋ ์ง ์ด๋ฌํ ์ ์ฝ ์กฐ๊ฑด๊ณผ ํจ๊ป ์๋ํ ์ ์๋ ์ ์ ํ ํด์ฑ ์๊ณ ๋ฆฌ์ฆ์ ๋ํด ์๊ณ ์์ต๋๊น? ๊ฐ์ฌ ํด์!
Tuple.Create(...).GetHashCode()
์์ต๋๋ค. ๋ถ๋ช
ํ ํ ๋น์ด ๋ฐ์ํ์ง๋ง ์์ธ๋ฅผ ๋์ง๋ ๊ฒ๋ณด๋ค ๋์ ๊ฒ ๊ฐ์ต๋๋ค.
์ฌ์ฉ์์๊ฒ System.ValueTuple
๋ฅผ ์ค์นํ๋ผ๊ณ ๋งํ ์ ์๋ ์ด์ ๊ฐ ์์ต๋๊น? ๋ด์ฅ ์ธ์ด ๊ธฐ๋ฅ์ด๊ธฐ ๋๋ฌธ์ System.ValueTuple ํจํค์ง๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ ํ๋ซํผ๊ณผ ๋งค์ฐ ํธํ๋ฉ๋๋ค.
๋ถ๋ช ํ ํ ๋น์ด ๋ฐ์ํ์ง๋ง ์์ธ๋ฅผ ๋์ง๋ ๊ฒ๋ณด๋ค ๋์ ๊ฒ ๊ฐ์ต๋๋ค.
์. ํ ๋น์ ์ผ์ผํค์ง ์๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ฌ์ฉ์์๊ฒ System.ValueTuple์ ์ค์นํ๋ผ๊ณ ๋งํ ์ ์๋ ์ด์ ๊ฐ ์์ต๋๊น?
ValueTuple ์ ๊ทผ ๋ฐฉ์์ ์์ฑํ๋ฉด ์ด๋ ๋์์ด ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ค์ ๋งํ์ง๋ง, ์ฌ์ฉ์๊ฐ ๊ตฌ์กฐ๋ฅผ ํฌ๊ฒ ๋ณ๊ฒฝํ์ง ์๊ณ ํ์ฌ ์ฝ๋๋ฅผ ๊ตฌ์กฐํํ ๋ฐฉ์์ ๋ง๋ ์ข์ ๊ฒ์ ์์ฑํ ์ ์๋ค๋ฉด ์ข์ ๊ฒ์ ๋๋ค.
VB ์ฌ์ฉ์๋ ์ด ๋ฌธ์ ๋ฅผ ํฉ๋ฆฌ์ ์ธ ๋ฐฉ์์ผ๋ก ํด๊ฒฐํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์์ด์ผ ํ๋ ๊ฒ ๊ฐ์ต๋๋ค. :) ํ์ง๋ง ๊ทธ๋ฌํ ์ ๊ทผ ๋ฐฉ์์ ์ ๋ฅผ ํผํ๊ณ ์์ต๋๋ค. :)
@CyrusNajmabadi , ์ฌ์ฉ์ ์ฝ๋์์ ์์ฒด ํด์ ๊ณ์ฐ์ ์ํํด์ผ ํ๋ ๊ฒฝ์ฐ CRC32๊ฐ ํ ์ด๋ธ ์กฐํ์ XOR์ ์กฐํฉ์ด๊ธฐ ๋๋ฌธ์ ์๋ํ ์ ์์ต๋๋ค(๊ทธ๋ฌ๋ ์ค๋ฒํ๋กํ ์ ์๋ ์ฐ์ ์ ์๋). ๊ทธ๋ฌ๋ ๋ช ๊ฐ์ง ๋จ์ ์ด ์์ต๋๋ค.
์์ง ํ๊ณ ์์ง ์๋ค๋ฉด XXHash๊ฐ ํจ์ฌ ๋ ๋์ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ HashCode ์ ํ์ ๊ฐ์งํ๊ณ ๊ฐ๋ฅํ๋ฉด ์ด๋ฅผ ์ฌ์ฉํ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
@morganbr ์ฐธ์กฐ https://github.com/dotnet/roslyn/pull/24161
์ฐ๋ฆฌ๋ ๋ค์์ ์ํํฉ๋๋ค.
Return (a, b, c, ...).GetHashCode()
์์ฑ'3d'๋ ์ ๋ง ์ํ๊น์ด ์ผ์ ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก VB๋ฅผ ์ฌ์ฉํ์ง๋ง ValueTuple ๋๋ ์ต์ ์์คํ ์ ์ฌ์ฉํ์ง ์๋ ์ฌ๋์ ์ฐ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ํฉ๋ฆฌ์ ์ธ ํด์ ์๊ณ ๋ฆฌ์ฆ์ ์์ฑํ ์ ์์ต๋๋ค.
์ฝ๋ ์ด๋๊ฐ์ 256 ํญ๋ชฉ ์กฐํ ํ ์ด๋ธ์ ๋ฃ์ด์ผ ํฉ๋๋ค.
์ด๊ฒ์ ์์ ํ ๋ง์ด ์์ ๊ฒ์ ๋๋ค :)
ํ ์ด๋ธ ์์ฑ ์ฝ๋๋ ๋ถ์พํ๊ฐ์? ์ ์ด๋ Wikipedia์ ์ ๋ฅผ ๋ณด๋ฉด ์ฝ๋๊ฐ ๋ง์ง ์์ต๋๋ค(๊ทธ๋ฌ๋ ์ฌ์ ํ ์ฌ์ฉ์ ์์ค์ ์ด๋๊ฐ์ ์์ด์ผ ํจ).
์ฐธ์กฐ๋ ์ด์ ๋ธ๋ฆฌ๋ฅผ ํตํด ์ฌ์ฉํ ์ ์์ ๋ (ํจ์ฌ ๋ ๊ฐ๋จํ) ์ปดํ์ผ๋ฌ ์์ฑ ํด๋์ค ์ ์๋ฅผ ์ฌ์ฉํ์ฌ Roslyn์ด (IL๊ณผ ํจ๊ป) HashCode ์์ค๋ฅผ ํ๋ก์ ํธ์ ์ถ๊ฐํ๋ ๊ฒ์ด ์ผ๋ง๋ ๋์ฐํ ๊น์?
์ฐธ์กฐ๋ ์ด์ ๋ธ๋ฆฌ๋ฅผ ํตํด ์ฌ์ฉํ ์ ์์ ๋ Roslyn์ด (ํจ์ฌ ๋ ๊ฐ๋จํ) ์ปดํ์ผ๋ฌ ์์ฑ ํด๋์ค ์ ์๋ก ํ๋ ๊ฒ์ฒ๋ผ HashCode ์์ค๋ฅผ ํ๋ก์ ํธ์ ์ถ๊ฐํ๋ ๊ฒ์ด ์ผ๋ง๋ ๋์ฐํ ๊น์?
VB์์ ์ค๋ฒํ๋ก ์ํ์ด ์๋ํ๋๋ก ํ๋ ์ข์ ๋ฐฉ๋ฒ์ด ์๋ค๋ ์ฌ์ค์ ๋๋์ต๋๋ค.
๋ฐ๋ผ์ ์ต์ํ ๋ ๊ฐ์ ํจ๊ป ํด์ฑํ๋๋ผ๋ ๋ค์์ ์์ฑํด์ผ ํ ๊ฒ ๊ฐ์ต๋๋ค.
```c#
var hc1 = (๋จ์)(๊ฐ1?.GetHashCode() ?? 0); // ์ค๋ฒํ๋ก ๊ฐ๋ฅ
var hc2 = (๋จ์)(๊ฐ2?.GetHashCode() ?? 0); // ์ค๋ฒํ๋ก ๊ฐ๋ฅ
uint hash = MixEmptyState();
hash += 8; // can overflow
hash = QueueRound(hash, hc1);
hash = QueueRound(hash, hc2);
hash = MixFinal(hash);
return (int)hash; // can overflow
Note that this code already has 4 lines that can overflow. It also has two helper functions you need to call (i'm ignoring MixEmptyState as that seems more like a constant). MixFinal can *definitely* overflow:
```c#
private static uint MixFinal(uint hash)
{
hash ^= hash >> 15;
hash *= Prime2;
hash ^= hash >> 13;
hash *= Prime3;
hash ^= hash >> 16;
return hash;
}
QueueRound๊ฐ ํ ์ ์๋ ๊ฒ์ฒ๋ผ:
c#
private static uint QueueRound(uint hash, uint queuedValue)
{
hash += queuedValue * Prime3;
return Rol(hash, 17) * Prime4;
}
๊ทธ๋์ ๋๋ ์ด๊ฒ์ด ์ด๋ป๊ฒ ์๋ํ๋์ง ์์งํ ์์ง ๋ชปํฉ๋๋ค :(
Roslyn์ด (IL๊ณผ ํจ๊ป) (๋ง์) ํ๋ก์ ํธ์ HashCode ์์ค๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ด ์ผ๋ง๋ ๋์ฐํ ์ผ์ ๋๊น
์ด ์์ ์ ์ด๋ป๊ฒ ์์ํ์ญ๋๊น? ๊ณ ๊ฐ์ ๋ฌด์์ ์์ฑํ๊ณ ์ปดํ์ผ๋ฌ๋ ์ด์ ๋ํ ์๋ต์ผ๋ก ๋ฌด์์ ํฉ๋๊น?
๋ํ ์ด ๋ชจ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ๊ฒ์ .Net์ด ์ค๋ฒํ๋ก ์์ด uint์์ int32๋ก(๋๋ ๊ทธ ๋ฐ๋๋ก) ๋ณํํ๋ ํ๋ฉด API์ ์ด๋ฏธ ๋ ธ์ถ๋ ๊ณต๊ฐ ๋์ฐ๋ฏธ๊ฐ ์๋ ๊ฒฝ์ฐ์ ๋๋ค.
๊ทธ๊ฒ๋ค์ด ์กด์ฌํฉ๋๊น? ๊ทธ๋ ๋ค๋ฉด ์ค๋ฒํ๋ก ์์ด ์ ํ ์ฌ์ด๋ฅผ ์ด๋ํด์ผ ํ๋ ์ํฉ์ ์ด๋ฅผ ์ฌ์ฉํ์ฌ VB ๋ฒ์ ์ ์ฝ๊ฒ ์์ฑํ ์ ์์ต๋๋ค.
ํ ์ด๋ธ ์์ฑ ์ฝ๋๋ ๋ถ์พํ๊ฐ์?
๋๋ ๊ทธ๋ ๊ฒ ์๊ฐํฉ๋๋ค. ์ ๋ง์, ์ด๊ฒ์ ๊ณ ๊ฐ์ ๊ด์ ์์ ์๊ฐํ์ญ์์ค. ๊ทธ๋ค์ ๋จ์ง ํ๋ฅญํ๊ฒ ์์ฒด ํฌํจ๋๊ณ ํฉ๋ฆฌ์ ์ธ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํ๋ ๊ด์ฐฎ์ GetHashCode ๋ฉ์๋๋ฅผ ์ํฉ๋๋ค. ๊ทธ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ณ ๋ณด์กฐ ์ฐ๋ ๊ธฐ๋ก ์ฝ๋๋ฅผ ๋ถํ๋ฆฌ๋ ๊ฒ์ ๊ฝค ๋ถ์พํ ๊ฒ์ ๋๋ค. C# ๊ฒฝํ์ด ๊ด์ฐฎ์ ๊ฒ์ด๋ผ๋ ์ ์ ๊ฐ์ํ ๋ ๋ํ ๊ฝค ๋์ฉ๋๋ค.
์๋ช ๋ 64๋นํธ ์ ํ๊ณผ ์๋ช ๋์ง ์์ 64๋นํธ ์ ํ์ ์ผ๋ถ ์กฐํฉ์ผ๋ก ๋๋ ๊ทธ๋ก๋ถํฐ ์บ์คํ ํ์ฌ ๋๋ต์ ์ผ๋ก ์ฌ๋ฐ๋ฅธ ์ค๋ฒํ๋ก ๋์์ ์ป์ ์ ์์ต๋๋ค. ์ด์ ๊ฐ์ ๊ฒ(ํ ์คํธ๋์ง ์์์ผ๋ฉฐ VB ์บ์คํ ๊ตฌ๋ฌธ์ ๋ชจ๋ฆ ๋๋ค):
Dim hashCode = -252780983
hashCode = (Int32)((Int32)((Unt64)hashCode * -1521134295) + (UInt64)i.GetHashCode())
๋ค์์ด ์ค๋ฒํ๋ก๋์ง ์๋๋ค๋ ๊ฒ์ ์ด๋ป๊ฒ ์ ์ ์์ต๋๊น?
c#
(Int32)((Unt64)hashCode * -1521134295)
๋๋ ๊ทธ ๋ฌธ์ ์ ๋ํ ์ต์ข (int32) ์บ์คํธ?
์ค๋ฒํ๋ก ํ์ธ ๋ณํ ์์ ์ ์ฌ์ฉํ ์ค์ ๋ชฐ๋์ต๋๋ค. ์บ์คํ ํ๊ธฐ ์ ์ 32๋นํธ๋ก ๋ง์คํนํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
(Int32)(((Unt64)hashCode * -1521134295) & 0xFFFFFFFF)
uint32.Max ๊ฐ๋ Int32๋ก ๋ณํํ ๋ ์ค๋ฒํ๋ก๋๋ฏ๋ก ์๋ง๋ 31๋นํธ์ผ ๊ฒ์ ๋๋ค. :)
๊ฐ๋ฅํฉ๋๋ค. ์ถ์ ํ์ง๋ง ๊ฐ๋ฅํฉ๋๋ค :) ์ด ์ฝ๋์๋ ๋ง์ ์บ์คํธ๊ฐ ์์ต๋๋ค.
ํ์ธ. ์คํ ๊ฐ๋ฅํ ์๋ฃจ์ ์ด ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ค๋๋ ์ฐ๋ฆฌ๊ฐ ์์ฑํ๋ ์๊ณ ๋ฆฌ์ฆ์ ํต์ฌ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
c#
hashCode = hashCode * -1521134295 + j.GetHashCode();
64๋นํธ ์ํ์ ์ํํ๊ณ ์์ง๋ง "hashCode"๊ฐ 32๋นํธ๋ก ์ ํ๋์ด ์๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค. ๊ทธ๋ฌ๋ฉด <largest_32_bit> * -1521134295 + <largest_32_bit>
๋ 64๋นํธ๋ฅผ ์ค๋ฒํ๋กํ์ง ์์ต๋๋ค. ๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ ํญ์ 64๋นํธ๋ก ๊ณ์ฐ์ ์ํํ ๋ค์ 32๋นํธ(๋๋ 32๋นํธ)๋ก ์ ํํ์ฌ ๋ค์ ๋ผ์ด๋๊ฐ ์ค๋ฒํ๋ก๋์ง ์๋๋ก ํ ์ ์์ต๋๋ค.
๊ฐ์ฌ ํด์!
@MaStr11 @morganbr @sharwell ๊ณผ ์ฌ๊ธฐ ์๋ ๋ชจ๋ ์ฌ๋๋ค. VB์ ๋ํด ๋ค์์ ์์ฑํ๋๋ก ์ฝ๋๋ฅผ ์ ๋ฐ์ดํธํ์ต๋๋ค.
Dim hashCode As Long = 2118541809
hashCode = (hashCode * -1521134295 + a.GetHashCode()) And Integer.MaxValue
hashCode = (hashCode * -1521134295 + b.GetHashCode()) And Integer.MaxValue
Return CType(hashCode And Integer.MaxValue, Integer)
๋๊ตฐ๊ฐ๊ฐ ์ด๊ฒ์ด ์๋ฏธ๊ฐ ์๊ณ ์ฒดํฌ ๋ชจ๋๊ฐ ์ผ์ง ์ํ์์๋ ์ค๋ฒํ๋ก๋์ง ์์์ผํ๋์ง ํ์ธํ๊ธฐ ์ํด ์ ๋ฅผ ๊ฒ์ฌ ํ ์ ์์ต๋๊น?
@CyrusNajmabadi , ์ค๋ฒํ๋ก๋์ง๋ ์์ง๋ง(Int64.Max = Int32.Max*Int32.Max์ด๊ณ ์์๊ฐ ๊ทธ๋ณด๋ค ํจ์ฌ ์๊ธฐ ๋๋ฌธ์) ์์ ๋นํธ๋ฅผ 0์ผ๋ก ๋ง์คํนํ๋ฏ๋ก 31๋นํธ ํด์์ผ ๋ฟ์ ๋๋ค. ์์ ๋นํธ๋ฅผ ์ผ์ง ์ํ๋ก ๋๋ ๊ฒ์ด ์ค๋ฒํ๋ก๋ก ๊ฐ์ฃผ๋ฉ๋๊น?
@CyrusNajmabadi hashCode
A๋ Long
๋ก ์ด๋์๋ 0์์ ํ ์ Integer.MaxValue
. ์ ๋ด๊ฐ ์ด๊ฒ์ ๋ฐ๊ณ ์์ต๋๊น?
๊ทธ๋ฌ๋ ์๋์, ์ค์ ๋ก ๋์น ์๋ ์์ต๋๋ค.
Btw- ์ฐจ์ ์ฑ ํด์๋ฅผ ์ถ๊ฐํ๋ ๊ฒ๋ณด๋ค Roslyn์ด NuGet ํจํค์ง๋ฅผ ์ถ๊ฐํ๋๋ก ํ๊ณ ์ถ์ต๋๋ค.
๊ทธ๋ฌ๋ ์์ ๋นํธ๋ฅผ 0์ผ๋ก ๋ง์คํนํ๋ฏ๋ก 31๋นํธ ํด์์ผ ๋ฟ์ ๋๋ค. ์์ ๋นํธ๋ฅผ ์ผ์ง ์ํ๋ก ๋๋ ๊ฒ์ด ์ค๋ฒํ๋ก๋ก ๊ฐ์ฃผ๋ฉ๋๊น?
๊ทธ๊ฑด ์ข์ ์ง์ ์ด์ผ. ๋๋ ๋จ์๋ฅผ ์ฌ์ฉํ๋ ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ์ ๋ํด ์๊ฐํ๊ณ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ฐ๋ผ์ long์์ uint๋ก ์์ ํ๊ฒ ๋ณํํ๋ ค๋ฉด ๋ถํธ ๋นํธ๋ฅผ ํฌํจํ์ง ์์์ผ ํ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ๋ชจ๋ ๋ถํธ ์๋ ์ํ์ด๋ฏ๋ก ๊ฐ ํญ๋ชฉ์ ์ถ๊ฐํ ํ ํ์ 32๋นํธ๋ง ์ ์งํ๋๋ก 0xffffffff์ ๋ํด ๋ง์คํฌํ๋ ๊ฒ์ด ์ข์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ฐจ์ ์ฑ ํด์๋ฅผ ์ถ๊ฐํ๋ ๊ฒ๋ณด๋ค Roslyn์ด NuGet ํจํค์ง๋ฅผ ์ถ๊ฐํ๋๋ก ํ๊ณ ์ถ์ต๋๋ค.
์ฌ์ฉ์๊ฐ ์ํ๋ ๊ฒฝ์ฐ ์ด๋ฏธ ๊ทธ๋ ๊ฒ ํ ์ ์์ต๋๋ค. ์ด๊ฒ์ ์ฌ์ฉ์๊ฐ ์ด๋ฌํ ์ข ์์ฑ์ ์ถ๊ฐํ์ง ์๊ฑฐ๋ ์ถ๊ฐํ ์ ์๋ ๊ฒฝ์ฐ ์ํํ ์์ ์ ๋ํ ๊ฒ์ ๋๋ค. ์ด๊ฒ์ ๋ํ ์ฌ์ฉ์์๊ฒ ํฉ๋ฆฌ์ ์ผ๋ก '์ถฉ๋ถํ ์ข์' ํด์๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ ๊ดํ ๊ฒ์ ๋๋ค. ์ฆ, ์ฌ๋๋ค์ด ์์ฃผ ์ทจํ๋ ์ผ๋ฐ์ ์ธ "x + y + z" ์ ๊ทผ ๋ฐฉ์๋ณด๋ค ๋ ๋์ ๊ฒ์ ๋๋ค. ๋ชจ๋ ์ฌ์ฉ์์ ๋ํ ํด์ฑ๊ณผ ๊ด๋ จํ์ฌ '์ต์ '์ด ๋ฌด์์ธ์ง์ ๋ํ ์ข์ ์ ์๊ฐ ์๊ธฐ ๋๋ฌธ์ '์ต์ '์ผ๋ก ์๋๋์ง ์์์ต๋๋ค. ์ฌ๊ธฐ์ ์ฐ๋ฆฌ๊ฐ ์ทจํ๊ณ ์๋ ์ ๊ทผ ๋ฐฉ์์ ์ต๋ช ์ ํ์ ๋ํด ์ปดํ์ผ๋ฌ์์ ์ด๋ฏธ ๋ด๋ณด๋ธ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค. ์ฌ์ฉ์ ์ฝ๋์ ๋ง์ ๋ณต์ก์ฑ์ ์ถ๊ฐํ์ง ์์ผ๋ฉด์ ์๋นํ ์ข์ ๋์์ ๋ณด์ฌ์ค๋๋ค. ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ์ ์ ๋ ๋ง์ ์ฌ์ฉ์๊ฐ ์์ผ๋ก ๋์๊ฐ ์ ์๊ฒ ๋๋ฉด์ ์์ํ ์ฌ๋ผ์ง๊ณ ๋๋ถ๋ถ์ ์ฌ๋๋ค์๊ฒ HashCode.Combine์ผ๋ก ๋์ฒด๋ ์ ์์ต๋๋ค.
๊ทธ๋์ ๋๋ ์ฝ๊ฐ์ ์์ ์ ํ๊ณ ๋ชจ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค๊ณ ์๊ฐํ๋ ๋ค์์ ์๊ฐํด ๋์ต๋๋ค.
Dim hashCode As Long = 2118541809
hashCode = (hashCode * -1521134295 + a.GetHashCode()).GetHashCode()
hashCode = (hashCode * -1521134295 + b.GetHashCode()).GetHashCode()
Return CType(hashCode, Integer)
ํฅ๋ฏธ๋ก์ด์ด ์ํ์ ํนํ ํธ์ถ .GetHashCode()
์ ์ํด ์์ฑ ๋ Int64 ๊ฐ์ (hashCode * -1521134295 + a.GetHashCode())
. ์ด 64๋นํธ ๊ฐ์ ๋ํด .GetHashCode๋ฅผ ํธ์ถํ๋ฉด ์ฐ๋ฆฌ์ ์๊ตฌ์ ๋ง๋ ๋ ๊ฐ์ง ์ข์ ์์ฑ์ด ์์ต๋๋ค. ์ฒซ์งธ, hashCode๊ฐ ํฉ๋ฒ์ ์ธ int32 ๊ฐ๋ง ์ ์ฅํ๋๋ก ํฉ๋๋ค(์ต์ข
๋ฐํ ์บ์คํธ๋ฅผ ํญ์ ์์ ํ๊ฒ ์ํํ ์ ์๋๋ก ํจ). ๋์งธ, ์์
์ค์ธ int64 ์์ ๊ฐ์ ์์ 32๋นํธ์์ ์ค์ํ ์ ๋ณด๋ฅผ ์์ง ์๋๋ก ํฉ๋๋ค.
@CyrusNajmabadi ์ค์ ๋ก ํจํค์ง ์ค์น๋ฅผ ์ ์ํ๋ ๊ฒ์ด ์ ๊ฐ ์ง๋ฌธํ ๊ฒ์ ๋๋ค. ๋ด๊ฐ ํด์ผ ํ๋ ์ผ์์ ๊ตฌํด์ค๋๋ค.
HashCode๋ฅผ ์ ๋ ฅํ๋ฉด MS nuget ํจํค์ง์ System.HashCode๊ฐ ์ ๊ณต๋๋ฉด Roslyn์ด ์ ๊ณตํฉ๋๋ค.
์กด์ฌํ์ง ์๋ GetHashCode ์ค๋ฒ๋ก๋๋ฅผ ์์ฑํ๊ณ ๋์ผํ ์์ ์ผ๋ก ํจํค์ง๋ฅผ ์ค์นํ๊ธฐ๋ฅผ ์ํฉ๋๋ค.
๋๋ถ๋ถ์ ์ฌ์ฉ์์๊ฒ ์ ์ ํ ์ ํ์ด ์๋๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ข ์์ฑ์ ์ถ๊ฐํ๋ ๊ฒ์ ์ฌ์ฉ์๊ฐ ๊ฐ์ ๋ก ์ํํด์๋ ์ ๋๋ ๋งค์ฐ ๋ฌด๊ฑฐ์ด ์์ ์ ๋๋ค. ์ฌ์ฉ์๋ ์ด๋ฌํ ์ ํ์ ํ ์ ์ ํ ์๊ธฐ๋ฅผ ๊ฒฐ์ ํ ์ ์์ผ๋ฉฐ IDE๋ ์ด๋ฅผ ์กด์คํฉ๋๋ค. ๊ทธ๊ฒ์ด ์ฐ๋ฆฌ๊ฐ ์ง๊ธ๊น์ง ๋ชจ๋ ๊ธฐ๋ฅ์ ๋ํด ์ทจํ ์ ๊ทผ ๋ฐฉ์์ด์๊ณ ์ฌ๋๋ค์ด ์ข์ํ๋ ๊ฑด๊ฐํ ๋ฐฉ์์ด์์ต๋๋ค.
์ฐธ๊ณ : ์ฐธ์กฐ๋ฅผ ์ถ๊ฐํ๊ธฐ ์ํด ์ด API๊ฐ ํฌํจ๋ nuget ํจํค์ง๋ ๋ฌด์์ ๋๊น?
๊ตฌํ์ System.Private.CoreLib.dll์ ์์ผ๋ฏ๋ก ๋ฐํ์ ํจํค์ง์ ์ผ๋ถ๋ก ์ ๊ณต๋ฉ๋๋ค. ๊ณ์ฝ์ System.Runtime.dll์ ๋๋ค.
ํ์ธ. ์ด ๊ฒฝ์ฐ ์ฌ์ฉ์๊ฐ ์ต์ ๋์ ํ๋ ์์ํฌ๋ก ์ด๋ํ ๋ ์ด ๋ฉ์์ง๋ฅผ ๋ฐ๋ ๊ฒ์ฒ๋ผ ๋ค๋ฆฝ๋๋ค. ๊ทธ๋ฐ ์ข ๋ฅ์ ์ผ์ ๋ด๊ฐ ์ฌ์ฉ์์ ํ๋ก์ ํธ์ "Equals+hashcode ์์ฑ"์ ์ํํ๋๋ก ํ๋ ๋จ๊ณ๊ฐ ์๋๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๊ฒฐ์
AddRange
๋ฉ์๋๋ฅผ ์ ๊ฑฐํด์ผ ํฉ๋๋ค. ๋ฐฐ์ด์ ๋งค์ฐ ์์ฃผ ๋ํ๋ ๊ฐ๋ฅ์ฑ์ด ๋ค์ ๋ฎ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ผ๋จ ๋ ํฐ ๋ฐฐ์ด์ด ๊ด๋ จ๋๋ฉด ๋ฌธ์ ๋ ๊ณ์ฐ์ ์บ์ํด์ผ ํ๋์ง ์ฌ๋ถ์ ๋๋ค. ํธ์ถ ์ธก์์ for ๋ฃจํ๋ฅผ ๋ณด๋ฉด ๊ทธ๊ฒ์ ๋ํด ์๊ฐํ ํ์๊ฐ ์์์ ๋ถ๋ช ํ ์ ์ ์์ต๋๋ค.IEnumerable
์ค๋ฒ๋ก๋๋ฅผAddRange
์ ์ถ๊ฐํ๊ณ ์ถ์ง ์์ต๋๋ค.string
์StringComparison
๊ฐ ๊ฑธ๋ฆฌ๋string
Add
๋ํ ์ค๋ฒ๋ก๋๊ฐ ํ์ํ์ง ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์,IEqualityComparer
ํตํด ํธ์ถํ๋ ๊ฒ๋ณด๋ค ๋ ํจ์จ์ ์ผ ์ ์์ง๋ง ๋์ค์ ์์ ํ ์ ์์ต๋๋ค.GetHashCode
๋ฅผ ์ค๋ฅ์ ํจ๊ป ์ฌ์ฉ๋์ง ์๋ ๊ฒ์ผ๋ก ํ์ํ๋ ๊ฒ์ ์ข์ ์๊ฐ์ด์ง๋ง ํ ๋จ๊ณ ๋ ๋์๊ฐ IntelliSense์์ ์จ๊ธธ ์๋ ์์ต๋๋ค.์ด๊ฒ์ ์ฐ๋ฆฌ์๊ฒ ๋ค์์ ๋จ๊น๋๋ค.
```C#(T1 ๊ฐ1);(T1 ๊ฐ1, T2 ๊ฐ2);(T1 ๊ฐ1, T2 ๊ฐ2, T3 ๊ฐ3);(T1 ๊ฐ1, T2 ๊ฐ2, T3 ๊ฐ3, T4 ๊ฐ4);(T1 ๊ฐ1, T2 ๊ฐ2, T3 ๊ฐ3, T4 ๊ฐ4, T5 ๊ฐ5);(T1 ๊ฐ1, T2 ๊ฐ2, T3 ๊ฐ3, T4 ๊ฐ4, T5 ๊ฐ5, T6 ๊ฐ6);(T1 ๊ฐ1, T2 ๊ฐ2, T3 ๊ฐ3, T4 ๊ฐ4, T5 ๊ฐ5, T6 ๊ฐ6, T7 ๊ฐ7);(T1 ๊ฐ1, T2 ๊ฐ2, T3 ๊ฐ3, T4 ๊ฐ4, T5 ๊ฐ5, T6 ๊ฐ6, T7 ๊ฐ7, T8 ๊ฐ8);
// ์ฝ์ด ์ด์ ๋ธ๋ฆฌ์ ์์ ๊ฒ์ ๋๋ค.
// .NET ํ๋ ์์ํฌ: mscorlib
// .NET ์ฝ์ด : System.Runtime / System.Private.CoreLib
๋ค์์คํ์ด์ค ์์คํ
{
๊ณต๊ฐ ๊ตฌ์กฐ์ฒด ํด์ ์ฝ๋
{
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
public static int ๊ฒฐํฉ
}
```