On 10/11/2016 05:45 AM, Temtaime wrote:
void popFront7(ref char[] s) @trusted pure nothrow
{
import core.bitop;
auto v = 7 - bsr(~s[0] | 1);
s = s[v > 6 ? 1 : (v ? (v > s.length ? s.length : v) : 1)..$];
}
Please check this.
Thanks. This does a lot of work on the frequent path c < 0x80:
pure nothrow @trusted void example.popFront7(ref char[]):
movq 8(%rdi), %rax
movzbl (%rax), %ecx
xorq $254, %rcx
orq $1, %rcx
bsrq %rcx, %rcx
notl %ecx
addl $8, %ecx
cmpl $6, %ecx
jg .LBB0_2
testl %ecx, %ecx
je .LBB0_2
movslq %ecx, %rdx
movq (%rdi), %rcx
cmpq %rcx, %rdx
cmovaq %rcx, %rdx
jmp .LBB0_3
.LBB0_2:
movq (%rdi), %rcx
movl $1, %edx
.LBB0_3:
addq %rdx, %rax
subq %rdx, %rcx
movq %rcx, (%rdi)
movq %rax, 8(%rdi)
retq
So I changed it to:
void popFront7(ref char[] s) @trusted pure nothrow
{
immutable c = s[0];
if (c < 0x80) {
s = s.ptr[1 .. s.length];
} else {
import core.bitop;
uint v = 7 - bsr(~c | (c > 0xfd) << 6u);
s = s.ptr[v > s.length ? s.length : v .. s.length];
}
}
That's about as large as the baseline.
Andrei