The best you can do is to do a linear comparison. However, you can use some architecture-specific tricks to greatly speed up the comparison by comparing word by word instead of byte by byte. The naive but portable approach might look like this:
bool all_bytes_equal(const char* buffer, size_t len) {
char c = buffer[0];
for(size_t i = 1; i < len; ++i)
if(buffer[i] != c)
return false;
return true;
}
But if your architecture supports rotated shifts, you could easily speed this up by running the comparisons 4 bytes at a time on a 32-bit architecture, or 8 bytes at a time on a 64-bit architecture:
// For x86-64 architectures with ROTL/ROTR instruction support
bool all_bytes_equal(const char* buffer, size_t len) {
const uint64_t* word_buf = (const uint64_t*) buffer;
for(size_t i = 0; i < len / 8; ++i)
if(word_buf[i] != _rotl64(word_buf[i], 8))
return false;
return true;
}
If your architecture supports SSE/AVX, you could speed this up even further by vectorizing the rotate shifts (below assumes AVX512, but you can replace __m512
with __m256
or __m128
, and replace the _mm512_*
family of functions with _mm256_*
or _mm_*
, and replace the loop increment accordingly):
bool all_bytes_equal(const char* buffer, size_t len) {
for(size_t i = 0; i < len / 512; i += 512) {
__m512 word = _mm512_load_epi64(buffer + i);
if(_mm512_testn_epi64_mask(word, _mm512_rol_epi64(word, 8)))
return false;
}
return true;
}
The bottom two examples make a few assumptions about the alignment of the buffer, but you can easily add code to them to deal with unaligned bytes at the beginning/end of the buffer.