diff --git a/compare_be.go b/compare_be.go new file mode 100644 index 0000000..92d757c --- /dev/null +++ b/compare_be.go @@ -0,0 +1,25 @@ +//go:build armbe || arm64be || m68k || mips || mips64 || mips64p32 || ppc || ppc64 || s390 || s390x || shbe || sparc || sparc64 + +package ulid + +// Compare returns an integer comparing id and other lexicographically. +// The result will be 0 if id==other, -1 if id < other, and +1 if id > other. +func (id ULID) Compare(other ULID) int { + ih := uint64(id[0x00]) | uint64(id[0x01])<<8 | uint64(id[0x02])<<16 | uint64(id[0x03])<<24 | uint64(id[0x04])<<32 | uint64(id[0x05])<<40 | uint64(id[0x06])<<48 | uint64(id[0x07])<<56 + oh := uint64(other[0x00]) | uint64(other[0x01])<<8 | uint64(other[0x02])<<16 | uint64(other[0x03])<<24 | uint64(other[0x04])<<32 | uint64(other[0x05])<<40 | uint64(other[0x06])<<48 | uint64(other[0x07])<<56 + if ih > oh { + return 1 + } + if ih < oh { + return -1 + } + il := uint64(id[0x08]) | uint64(id[0x09])<<8 | uint64(id[0x0A])<<16 | uint64(id[0x0B])<<24 | uint64(id[0x0C])<<32 | uint64(id[0x0D])<<40 | uint64(id[0x0E])<<48 | uint64(id[0x0F])<<56 + ol := uint64(other[0x08]) | uint64(other[0x09])<<8 | uint64(other[0x0A])<<16 | uint64(other[0x0B])<<24 | uint64(other[0x0C])<<32 | uint64(other[0x0D])<<40 | uint64(other[0x0E])<<48 | uint64(other[0x0F])<<56 + if il > ol { + return 1 + } + if il < ol { + return -1 + } + return 0 +} diff --git a/compare_le.go b/compare_le.go new file mode 100644 index 0000000..8c2bff1 --- /dev/null +++ b/compare_le.go @@ -0,0 +1,25 @@ +//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh || wasm + +package ulid + +// Compare returns an integer comparing id and other lexicographically. +// The result will be 0 if id==other, -1 if id < other, and +1 if id > other. +func (id ULID) Compare(other ULID) int { + ih := uint64(id[0x07]) | uint64(id[0x06])<<8 | uint64(id[0x05])<<16 | uint64(id[0x04])<<24 | uint64(id[0x03])<<32 | uint64(id[0x02])<<40 | uint64(id[0x01])<<48 | uint64(id[0x00])<<56 + oh := uint64(other[0x07]) | uint64(other[0x06])<<8 | uint64(other[0x05])<<16 | uint64(other[0x04])<<24 | uint64(other[0x03])<<32 | uint64(other[0x02])<<40 | uint64(other[0x01])<<48 | uint64(other[0x00])<<56 + if ih > oh { + return 1 + } + if ih < oh { + return -1 + } + il := uint64(id[0x0F]) | uint64(id[0x0E])<<8 | uint64(id[0x0D])<<16 | uint64(id[0x0C])<<24 | uint64(id[0x0B])<<32 | uint64(id[0x0A])<<40 | uint64(id[0x09])<<48 | uint64(id[0x08])<<56 + ol := uint64(other[0x0F]) | uint64(other[0x0E])<<8 | uint64(other[0x0D])<<16 | uint64(other[0x0C])<<24 | uint64(other[0x0B])<<32 | uint64(other[0x0A])<<40 | uint64(other[0x09])<<48 | uint64(other[0x08])<<56 + if il > ol { + return 1 + } + if il < ol { + return -1 + } + return 0 +} diff --git a/ulid.go b/ulid.go index 77e9ddd..0b05803 100644 --- a/ulid.go +++ b/ulid.go @@ -15,7 +15,6 @@ package ulid import ( "bufio" - "bytes" "database/sql/driver" "encoding/binary" "errors" @@ -490,12 +489,6 @@ func (id *ULID) SetEntropy(e []byte) error { return nil } -// Compare returns an integer comparing id and other lexicographically. -// The result will be 0 if id==other, -1 if id < other, and +1 if id > other. -func (id ULID) Compare(other ULID) int { - return bytes.Compare(id[:], other[:]) -} - // Scan implements the sql.Scanner interface. It supports scanning // a string or byte slice. func (id *ULID) Scan(src interface{}) error { diff --git a/ulid_test.go b/ulid_test.go index 5ca70ae..a78cb4a 100644 --- a/ulid_test.go +++ b/ulid_test.go @@ -892,7 +892,20 @@ func BenchmarkSetEntropy(b *testing.B) { } } -func BenchmarkCompare(b *testing.B) { +func OldCompare(id, other ulid.ULID) int { + return bytes.Compare(id[:], other[:]) +} + +func BenchmarkOldCompare(b *testing.B) { + id, other := ulid.MustNew(12345, nil), ulid.MustNew(54321, nil) + b.SetBytes(int64(len(id) * 2)) + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = OldCompare(id, other) + } +} + +func BenchmarkNewCompare(b *testing.B) { id, other := ulid.MustNew(12345, nil), ulid.MustNew(54321, nil) b.SetBytes(int64(len(id) * 2)) b.ResetTimer()