mirror of
https://github.com/pgvector/pgvector.git
synced 2026-06-06 05:51:21 +08:00
Improved performance of bit distance functions - #519
Co-authored-by: Nathan Bossart <nathan@postgresql.org> Co-authored-by: "Jonathan S. Katz" <jkatz@users.noreply.github.com>
This commit is contained in:
2
Makefile
2
Makefile
@@ -3,7 +3,7 @@ EXTVERSION = 0.6.2
|
||||
|
||||
MODULE_big = vector
|
||||
DATA = $(wildcard sql/*--*.sql)
|
||||
OBJS = src/bitvector.o src/halfutils.o src/halfvec.o src/hnsw.o src/hnswbuild.o src/hnswinsert.o src/hnswscan.o src/hnswutils.o src/hnswvacuum.o src/ivfbuild.o src/ivfflat.o src/ivfinsert.o src/ivfkmeans.o src/ivfscan.o src/ivfutils.o src/ivfvacuum.o src/sparsevec.o src/vector.o
|
||||
OBJS = src/bitutils.o src/bitvector.o src/halfutils.o src/halfvec.o src/hnsw.o src/hnswbuild.o src/hnswinsert.o src/hnswscan.o src/hnswutils.o src/hnswvacuum.o src/ivfbuild.o src/ivfflat.o src/ivfinsert.o src/ivfkmeans.o src/ivfscan.o src/ivfutils.o src/ivfvacuum.o src/sparsevec.o src/vector.o
|
||||
HEADERS = src/halfvec.h src/sparsevec.h src/vector.h
|
||||
|
||||
TESTS = $(wildcard test/sql/*.sql)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
EXTENSION = vector
|
||||
EXTVERSION = 0.6.2
|
||||
|
||||
OBJS = src\bitvector.obj src\halfutils.obj src\halfvec.obj src\hnsw.obj src\hnswbuild.obj src\hnswinsert.obj src\hnswscan.obj src\hnswutils.obj src\hnswvacuum.obj src\ivfbuild.obj src\ivfflat.obj src\ivfinsert.obj src\ivfkmeans.obj src\ivfscan.obj src\ivfutils.obj src\ivfvacuum.obj src\sparsevec.obj src\vector.obj
|
||||
OBJS = src\bitutils.obj src\bitvector.obj src\halfutils.obj src\halfvec.obj src\hnsw.obj src\hnswbuild.obj src\hnswinsert.obj src\hnswscan.obj src\hnswutils.obj src\hnswvacuum.obj src\ivfbuild.obj src\ivfflat.obj src\ivfinsert.obj src\ivfkmeans.obj src\ivfscan.obj src\ivfutils.obj src\ivfvacuum.obj src\sparsevec.obj src\vector.obj
|
||||
HEADERS = src\halfvec.h src\sparsevec.h src\vector.h
|
||||
|
||||
REGRESS = bit_functions btree_halfvec btree_sparsevec btree_vector cast copy halfvec_functions halfvec_input hnsw_bit_hamming hnsw_bit_jaccard hnsw_halfvec_cosine hnsw_halfvec_ip hnsw_halfvec_l2 hnsw_options hnsw_sparsevec_cosine hnsw_sparsevec_ip hnsw_sparsevec_l2 hnsw_unlogged hnsw_vector_cosine hnsw_vector_ip hnsw_vector_l2 ivfflat_halfvec_cosine ivfflat_halfvec_ip ivfflat_halfvec_l2 ivfflat_options ivfflat_unlogged ivfflat_vector_cosine ivfflat_vector_ip ivfflat_vector_l2 sparsevec_functions sparsevec_input vector_functions vector_input
|
||||
|
||||
217
src/bitutils.c
Normal file
217
src/bitutils.c
Normal file
@@ -0,0 +1,217 @@
|
||||
#include "postgres.h"
|
||||
|
||||
#include "bitutils.h"
|
||||
#include "port/pg_bitutils.h"
|
||||
|
||||
#ifdef BIT_DISPATCH
|
||||
#include <immintrin.h>
|
||||
|
||||
#if defined(HAVE__GET_CPUID)
|
||||
#include <cpuid.h>
|
||||
#else
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define TARGET_AVX512_POPCOUNT
|
||||
#else
|
||||
#define TARGET_AVX512_POPCOUNT __attribute__((target("avx512f,avx512vpopcntdq")))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Disable for LLVM due to crash with bitcode generation */
|
||||
#if defined(USE_TARGET_CLONES) && !defined(__POPCNT__) && !defined(__llvm__)
|
||||
#define BIT_TARGET_CLONES __attribute__((target_clones("default", "popcnt")))
|
||||
#else
|
||||
#define BIT_TARGET_CLONES
|
||||
#endif
|
||||
|
||||
/* Use built-ins when possible for inlining */
|
||||
#if defined(HAVE__BUILTIN_POPCOUNT) && defined(HAVE_LONG_INT_64)
|
||||
#define popcount64(x) __builtin_popcountl(x)
|
||||
#elif defined(HAVE__BUILTIN_POPCOUNT) && defined(HAVE_LONG_LONG_INT_64)
|
||||
#define popcount64(x) __builtin_popcountll(x)
|
||||
#elif !defined(_MSC_VER)
|
||||
/* Fails to resolve with MSVC */
|
||||
#define popcount64(x) pg_popcount64(x)
|
||||
#endif
|
||||
|
||||
uint64 (*BitHammingDistance) (uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance);
|
||||
double (*BitJaccardDistance) (uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb);
|
||||
|
||||
BIT_TARGET_CLONES static uint64
|
||||
BitHammingDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance)
|
||||
{
|
||||
#ifdef popcount64
|
||||
for (; bytes >= sizeof(uint64); bytes -= sizeof(uint64))
|
||||
{
|
||||
uint64 axs;
|
||||
uint64 bxs;
|
||||
|
||||
/* Ensure aligned */
|
||||
memcpy(&axs, ax, sizeof(uint64));
|
||||
memcpy(&bxs, bx, sizeof(uint64));
|
||||
|
||||
distance += popcount64(axs ^ bxs);
|
||||
|
||||
ax += sizeof(uint64);
|
||||
bx += sizeof(uint64);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (uint32 i = 0; i < bytes; i++)
|
||||
distance += pg_number_of_ones[ax[i] ^ bx[i]];
|
||||
|
||||
return distance;
|
||||
}
|
||||
|
||||
#ifdef BIT_DISPATCH
|
||||
TARGET_AVX512_POPCOUNT static uint64
|
||||
BitHammingDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance)
|
||||
{
|
||||
__m512i dist = _mm512_setzero_si512();
|
||||
|
||||
for (; bytes >= sizeof(__m512i); bytes -= sizeof(__m512i))
|
||||
{
|
||||
__m512i axs = _mm512_loadu_si512((const __m512i *) ax);
|
||||
__m512i bxs = _mm512_loadu_si512((const __m512i *) bx);
|
||||
|
||||
dist = _mm512_add_epi64(dist, _mm512_popcnt_epi64(_mm512_xor_si512(axs, bxs)));
|
||||
|
||||
ax += sizeof(__m512i);
|
||||
bx += sizeof(__m512i);
|
||||
}
|
||||
|
||||
distance += _mm512_reduce_add_epi64(dist);
|
||||
|
||||
return BitHammingDistanceDefault(bytes, ax, bx, distance);
|
||||
}
|
||||
#endif
|
||||
|
||||
BIT_TARGET_CLONES static double
|
||||
BitJaccardDistanceDefault(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb)
|
||||
{
|
||||
#ifdef popcount64
|
||||
for (; bytes >= sizeof(uint64); bytes -= sizeof(uint64))
|
||||
{
|
||||
uint64 axs;
|
||||
uint64 bxs;
|
||||
|
||||
/* Ensure aligned */
|
||||
memcpy(&axs, ax, sizeof(uint64));
|
||||
memcpy(&bxs, bx, sizeof(uint64));
|
||||
|
||||
ab += popcount64(axs & bxs);
|
||||
aa += popcount64(axs);
|
||||
bb += popcount64(bxs);
|
||||
|
||||
ax += sizeof(uint64);
|
||||
bx += sizeof(uint64);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (uint32 i = 0; i < bytes; i++)
|
||||
{
|
||||
ab += pg_number_of_ones[ax[i] & bx[i]];
|
||||
aa += pg_number_of_ones[ax[i]];
|
||||
bb += pg_number_of_ones[bx[i]];
|
||||
}
|
||||
|
||||
if (ab == 0)
|
||||
return 1;
|
||||
else
|
||||
return 1 - (ab / ((double) (aa + bb - ab)));
|
||||
}
|
||||
|
||||
#ifdef BIT_DISPATCH
|
||||
TARGET_AVX512_POPCOUNT static double
|
||||
BitJaccardDistanceAvx512Popcount(uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb)
|
||||
{
|
||||
__m512i abx = _mm512_setzero_si512();
|
||||
__m512i aax = _mm512_setzero_si512();
|
||||
__m512i bbx = _mm512_setzero_si512();
|
||||
|
||||
for (; bytes >= sizeof(__m512i); bytes -= sizeof(__m512i))
|
||||
{
|
||||
__m512i axs = _mm512_loadu_si512((const __m512i *) ax);
|
||||
__m512i bxs = _mm512_loadu_si512((const __m512i *) bx);
|
||||
|
||||
abx = _mm512_add_epi64(abx, _mm512_popcnt_epi64(_mm512_and_si512(axs, bxs)));
|
||||
aax = _mm512_add_epi64(aax, _mm512_popcnt_epi64(axs));
|
||||
bbx = _mm512_add_epi64(bbx, _mm512_popcnt_epi64(bxs));
|
||||
|
||||
ax += sizeof(__m512i);
|
||||
bx += sizeof(__m512i);
|
||||
}
|
||||
|
||||
ab += _mm512_reduce_add_epi64(abx);
|
||||
aa += _mm512_reduce_add_epi64(aax);
|
||||
bb += _mm512_reduce_add_epi64(bbx);
|
||||
|
||||
return BitJaccardDistanceDefault(bytes, ax, bx, ab, aa, bb);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BIT_DISPATCH
|
||||
#define CPU_FEATURE_OSXSAVE (1 << 27) /* F1 ECX */
|
||||
#define CPU_FEATURE_AVX512F (1 << 16) /* F7,0 EBX */
|
||||
#define CPU_FEATURE_AVX512VPOPCNTDQ (1 << 14) /* F7,0 ECX */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define TARGET_XSAVE
|
||||
#else
|
||||
#define TARGET_XSAVE __attribute__((target("xsave")))
|
||||
#endif
|
||||
|
||||
TARGET_XSAVE static bool
|
||||
SupportsAvx512Popcount()
|
||||
{
|
||||
unsigned int exx[4] = {0, 0, 0, 0};
|
||||
|
||||
#if defined(HAVE__GET_CPUID)
|
||||
__get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
|
||||
#else
|
||||
__cpuid(exx, 1);
|
||||
#endif
|
||||
|
||||
/* Check OS supports XSAVE */
|
||||
if ((exx[2] & CPU_FEATURE_OSXSAVE) != CPU_FEATURE_OSXSAVE)
|
||||
return false;
|
||||
|
||||
/* Check XMM, YMM, and ZMM registers are enabled */
|
||||
if ((_xgetbv(0) & 0xe6) != 0xe6)
|
||||
return false;
|
||||
|
||||
#if defined(HAVE__GET_CPUID)
|
||||
__get_cpuid_count(7, 0, &exx[0], &exx[1], &exx[2], &exx[3]);
|
||||
#else
|
||||
__cpuidex(exx, 7, 0);
|
||||
#endif
|
||||
|
||||
/* Check AVX512F */
|
||||
if ((exx[1] & CPU_FEATURE_AVX512F) != CPU_FEATURE_AVX512F)
|
||||
return false;
|
||||
|
||||
/* Check AVX512VPOPCNTDQ */
|
||||
return (exx[2] & CPU_FEATURE_AVX512VPOPCNTDQ) == CPU_FEATURE_AVX512VPOPCNTDQ;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
BitvecInit(void)
|
||||
{
|
||||
/*
|
||||
* Could skip pointer when single function, but no difference in
|
||||
* performance
|
||||
*/
|
||||
BitHammingDistance = BitHammingDistanceDefault;
|
||||
BitJaccardDistance = BitJaccardDistanceDefault;
|
||||
|
||||
#ifdef BIT_DISPATCH
|
||||
if (SupportsAvx512Popcount())
|
||||
{
|
||||
BitHammingDistance = BitHammingDistanceAvx512Popcount;
|
||||
BitJaccardDistance = BitJaccardDistanceAvx512Popcount;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
23
src/bitutils.h
Normal file
23
src/bitutils.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef BITUTILS_H
|
||||
#define BITUTILS_H
|
||||
|
||||
/* Only enable for more recent compilers */
|
||||
#if defined(__x86_64__) && defined(__GNUC__) && __GNUC__ >= 8
|
||||
#define BIT_DISPATCH
|
||||
#elif defined(__x86_64__) && defined(__clang_major__) && __clang_major__ >= 7
|
||||
#define BIT_DISPATCH
|
||||
#elif defined(_M_AMD64) && defined(_MSC_VER) && _MSC_VER >= 1920
|
||||
#define BIT_DISPATCH
|
||||
#endif
|
||||
|
||||
/* target_clones requires glibc */
|
||||
#if defined(BIT_DISPATCH) && defined(__gnu_linux__)
|
||||
#define USE_TARGET_CLONES
|
||||
#endif
|
||||
|
||||
extern uint64 (*BitHammingDistance) (uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 distance);
|
||||
extern double (*BitJaccardDistance) (uint32 bytes, unsigned char *ax, unsigned char *bx, uint64 ab, uint64 aa, uint64 bb);
|
||||
|
||||
void BitvecInit(void);
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "postgres.h"
|
||||
|
||||
#include "bitutils.h"
|
||||
#include "bitvector.h"
|
||||
#include "port/pg_bitutils.h"
|
||||
#include "utils/varbit.h"
|
||||
|
||||
#if PG_VERSION_NUM >= 160000
|
||||
@@ -46,17 +46,10 @@ hamming_distance(PG_FUNCTION_ARGS)
|
||||
{
|
||||
VarBit *a = PG_GETARG_VARBIT_P(0);
|
||||
VarBit *b = PG_GETARG_VARBIT_P(1);
|
||||
unsigned char *ax = VARBITS(a);
|
||||
unsigned char *bx = VARBITS(b);
|
||||
uint64 distance = 0;
|
||||
|
||||
CheckDims(a, b);
|
||||
|
||||
/* TODO Improve performance */
|
||||
for (uint32 i = 0; i < VARBITBYTES(a); i++)
|
||||
distance += pg_number_of_ones[ax[i] ^ bx[i]];
|
||||
|
||||
PG_RETURN_FLOAT8((double) distance);
|
||||
PG_RETURN_FLOAT8((double) BitHammingDistance(VARBITBYTES(a), VARBITS(a), VARBITS(b), 0));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -68,23 +61,8 @@ jaccard_distance(PG_FUNCTION_ARGS)
|
||||
{
|
||||
VarBit *a = PG_GETARG_VARBIT_P(0);
|
||||
VarBit *b = PG_GETARG_VARBIT_P(1);
|
||||
unsigned char *ax = VARBITS(a);
|
||||
unsigned char *bx = VARBITS(b);
|
||||
uint64 ab = 0;
|
||||
uint64 aa;
|
||||
uint64 bb;
|
||||
|
||||
CheckDims(a, b);
|
||||
|
||||
/* TODO Improve performance */
|
||||
for (uint32 i = 0; i < VARBITBYTES(a); i++)
|
||||
ab += pg_number_of_ones[ax[i] & bx[i]];
|
||||
|
||||
if (ab == 0)
|
||||
PG_RETURN_FLOAT8(1);
|
||||
|
||||
aa = pg_popcount((char *) ax, VARBITBYTES(a));
|
||||
bb = pg_popcount((char *) bx, VARBITBYTES(b));
|
||||
|
||||
PG_RETURN_FLOAT8(1 - (ab / ((double) (aa + bb - ab))));
|
||||
PG_RETURN_FLOAT8(BitJaccardDistance(VARBITBYTES(a), VARBITS(a), VARBITS(b), 0, 0, 0));
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "bitutils.h"
|
||||
#include "bitvector.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "common/shortest_dec.h"
|
||||
@@ -56,6 +57,7 @@ PGDLLEXPORT void _PG_init(void);
|
||||
void
|
||||
_PG_init(void)
|
||||
{
|
||||
BitvecInit();
|
||||
HalfvecInit();
|
||||
HnswInit();
|
||||
IvfflatInit();
|
||||
|
||||
@@ -28,6 +28,24 @@ SELECT hamming_distance('10101010101010101010', '01010101010101010101');
|
||||
20
|
||||
(1 row)
|
||||
|
||||
SELECT hamming_distance('101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101', '101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101');
|
||||
hamming_distance
|
||||
------------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
SELECT hamming_distance('101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101', '010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010');
|
||||
hamming_distance
|
||||
------------------
|
||||
513
|
||||
(1 row)
|
||||
|
||||
SELECT hamming_distance('110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011', '100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001');
|
||||
hamming_distance
|
||||
------------------
|
||||
2
|
||||
(1 row)
|
||||
|
||||
SELECT hamming_distance('', '');
|
||||
hamming_distance
|
||||
------------------
|
||||
@@ -86,6 +104,24 @@ SELECT jaccard_distance('10101010101010101010', '01010101010101010101');
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT jaccard_distance('101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101', '101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101');
|
||||
jaccard_distance
|
||||
------------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
SELECT jaccard_distance('101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101', '010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010');
|
||||
jaccard_distance
|
||||
------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT jaccard_distance('110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011', '100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001');
|
||||
jaccard_distance
|
||||
------------------
|
||||
0.5
|
||||
(1 row)
|
||||
|
||||
SELECT jaccard_distance('', '');
|
||||
jaccard_distance
|
||||
------------------
|
||||
|
||||
@@ -3,6 +3,9 @@ SELECT hamming_distance('111', '110');
|
||||
SELECT hamming_distance('111', '100');
|
||||
SELECT hamming_distance('111', '000');
|
||||
SELECT hamming_distance('10101010101010101010', '01010101010101010101');
|
||||
SELECT hamming_distance('101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101', '101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101');
|
||||
SELECT hamming_distance('101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101', '010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010');
|
||||
SELECT hamming_distance('110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011', '100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001');
|
||||
SELECT hamming_distance('', '');
|
||||
SELECT hamming_distance('111', '00');
|
||||
SELECT hamming_distance('111', '000'::varbit(4));
|
||||
@@ -15,6 +18,9 @@ SELECT jaccard_distance('1111', '1000');
|
||||
SELECT jaccard_distance('1111', '0000');
|
||||
SELECT jaccard_distance('1100', '1000');
|
||||
SELECT jaccard_distance('10101010101010101010', '01010101010101010101');
|
||||
SELECT jaccard_distance('101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101', '101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101');
|
||||
SELECT jaccard_distance('101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101', '010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010');
|
||||
SELECT jaccard_distance('110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011', '100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001');
|
||||
SELECT jaccard_distance('', '');
|
||||
SELECT jaccard_distance('1111', '000');
|
||||
SELECT jaccard_distance('1111', '0000'::varbit(5));
|
||||
|
||||
Reference in New Issue
Block a user