Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ハッシュ計算の最適化とリファクタリング #148

Merged
merged 1 commit into from
Sep 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions Source/Utf8Utility/Utf8Array.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Runtime.InteropServices;
using System.Text;
using CommunityToolkit.HighPerformance;
using CommunityToolkit.HighPerformance.Helpers;
using Utf8Utility.Helpers;
using Utf8Utility.Text;
#if NET6_0_OR_GREATER
Expand Down Expand Up @@ -116,13 +117,18 @@ public static Utf8Array Empty
/// UTF-8配列が空の場合は<see langword="true"/>、
/// それ以外は<see langword="false"/>を返します。
/// </returns>
[SuppressMessage("Style", "IDE0075:条件式を簡略化する", Justification = "最適化のため")]
public bool IsEmpty
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#if NET7_0_OR_GREATER

get => _value is null || _value.Length == 0;
#else
// インライン化された場合の最適化のため、三項演算子でtrue/falseを返す。
// https://github.com/dotnet/runtime/issues/4207
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[SuppressMessage("Style", "IDE0075:条件式を簡略化する", Justification = "最適化のため")]
get => (_value is null || _value.Length == 0) ? true : false;
#endif
}

/// <summary>
Expand Down Expand Up @@ -168,7 +174,7 @@ public bool Equals(Utf8Array other)
=> AsSpan().SequenceEqual(other.AsSpan());

/// <inheritdoc/>
public override int GetHashCode() => _value.GetDjb2HashCode();
public override int GetHashCode() => HashCode<byte>.Combine(AsSpan());

/// <inheritdoc/>
public override string ToString() => Encoding.UTF8.GetString(_value);
Expand Down Expand Up @@ -247,7 +253,7 @@ public int GetLength()
while ((int)index <= length)
{
// 最適化の関係でrefローカル変数にしてはいけない。
var value = Unsafe.As<byte, ulong>(ref Unsafe.AddByteOffset(ref _value.DangerousGetReference(), index));
var value = Unsafe.As<byte, ulong>(ref Unsafe.AddByteOffset(ref DangerousGetReference(), index));

var x = ((value >> 6) | (~value >> 7)) & Mask;
count += BitOperations.PopCount(x);
Expand All @@ -259,7 +265,7 @@ public int GetLength()
while ((int)index < ByteCount)
{
// 最適化の関係でrefローカル変数にしてはいけない。
var value = Unsafe.AddByteOffset(ref _value.DangerousGetReference(), index);
var value = Unsafe.AddByteOffset(ref DangerousGetReference(), index);

if ((value & 0xC0) != 0x80)
{
Expand Down Expand Up @@ -353,6 +359,7 @@ public bool IsEmptyOrWhiteSpace()
/// このメソッドは境界チェックを行いません。
/// </summary>
/// <returns>最初の要素への参照を返します。</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref byte DangerousGetReference() => ref _value.DangerousGetReference();

/// <summary>
Expand Down
3 changes: 2 additions & 1 deletion Source/Utf8Utility/Utf8ArrayDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Runtime.CompilerServices;
using System.Text;
using CommunityToolkit.HighPerformance;
using CommunityToolkit.HighPerformance.Helpers;
using Utf8Utility.Helpers;

namespace Utf8Utility;
Expand Down Expand Up @@ -163,7 +164,7 @@ public ref TValue GetValueRefOrNullRef(Utf8Array key)
public ref TValue GetValueRefOrNullRef(ReadOnlySpan<byte> key)
{
var entries = _entries;
var bucketIndex = GetBucketIndex(key.GetDjb2HashCode());
var bucketIndex = GetBucketIndex(HashCode<byte>.Combine(key));
var i = GetBucket(bucketIndex) - 1;

do
Expand Down