[Tarantool-patches] [PATCH v5 2/2] base64: improve decoder performance

Leonid Vasiliev lvasiliev at tarantool.org
Fri Dec 25 16:01:54 MSK 2020


Hi! Thank you for the patch.
LGTM.

On 25.12.2020 13:41, Sergey Nikiforov wrote:
> Unnecessary checks were removed from internal loops.
> Benchmark shows that performance is now ~1.19 times higher
> (release build, Intel Core I7-9700K, only one thread).
> ---
>   third_party/base64.c | 35 ++++++++++++++++++++++++++---------
>   1 file changed, 26 insertions(+), 9 deletions(-)
> 
> diff --git a/third_party/base64.c b/third_party/base64.c
> index 3350a98ff..2b2b61ba4 100644
> --- a/third_party/base64.c
> +++ b/third_party/base64.c
> @@ -257,10 +257,10 @@ base64_decode_block(const char *in_base64, int in_len,
>   		{
>   	case step_a:
>   			do {
> -				if (in_pos == in_end || out_pos >= out_end)
> +				if (in_pos >= in_end)
>   				{
>   					state->step = step_a;
> -					state->result = curr_byte;
> +					/* curr_byte is useless now. */
>   					return out_pos - out_bin;
>   				}
>   				fragment = base64_decode_value(*in_pos++);
> @@ -268,7 +268,7 @@ base64_decode_block(const char *in_base64, int in_len,
>   			curr_byte = (fragment & 0x03f) << 2;
>   	case step_b:
>   			do {
> -				if (in_pos == in_end || out_pos >= out_end)
> +				if (in_pos >= in_end)
>   				{
>   					state->step = step_b;
>   					state->result = curr_byte;
> @@ -276,14 +276,19 @@ base64_decode_block(const char *in_base64, int in_len,
>   				}
>   				fragment = base64_decode_value(*in_pos++);
>   			} while (fragment < 0);
> +			if (out_pos >= out_end)
> +			{
> +				/* We are losing some data. */
> +				state->step = step_b;
> +				state->result = curr_byte;
> +				return out_pos - out_bin;
> +			}
>   			curr_byte |= (fragment & 0x030) >> 4;
>   			*out_pos++ = curr_byte;
>   			curr_byte = (fragment & 0x00f) << 4;
> -			if (out_pos < out_end)
> -				*out_pos = curr_byte;
>   	case step_c:
>   			do {
> -				if (in_pos == in_end || out_pos >= out_end)
> +				if (in_pos >= in_end)
>   				{
>   					state->step = step_c;
>   					state->result = curr_byte;
> @@ -291,14 +296,19 @@ base64_decode_block(const char *in_base64, int in_len,
>   				}
>   				fragment = base64_decode_value(*in_pos++);
>   			} while (fragment < 0);
> +			if (out_pos >= out_end)
> +			{
> +				/* We are losing some data. */
> +				state->step = step_c;
> +				state->result = curr_byte;
> +				return out_pos - out_bin;
> +			}
>   			curr_byte |= (fragment & 0x03c) >> 2;
>   			*out_pos++ = curr_byte;
>   			curr_byte = (fragment & 0x003) << 6;
> -			if (out_pos < out_end)
> -				*out_pos = curr_byte;
>   	case step_d:
>   			do {
> -				if (in_pos == in_end || out_pos >= out_end)
> +				if (in_pos >= in_end)
>   				{
>   					state->step = step_d;
>   					state->result = curr_byte;
> @@ -306,6 +316,13 @@ base64_decode_block(const char *in_base64, int in_len,
>   				}
>   				fragment = base64_decode_value(*in_pos++);
>   			} while (fragment < 0);
> +			if (out_pos >= out_end)
> +			{
> +				/* We are losing some data. */
> +				state->step = step_d;
> +				state->result = curr_byte;
> +				return out_pos - out_bin;
> +			}
>   			curr_byte |= (fragment & 0x03f);
>   			*out_pos++ = curr_byte;
>   		}
> 


More information about the Tarantool-patches mailing list