authorgravatar for joad.nacer@gmail.comjoadnacer <joad.nacer@gmail.com> 2023-10-15 23:14:46+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-16 08:49:05-04:00
log7b9165b37576ed4c4962c0ad2afb62921524aa08
tree745976a8ed73184fcd587df96eec4ae12553075f
parent14efbf5ed1731058a616582d81223e23f43af128

std.mem: Improve writeIntSlice performance


1 files changed, 31 insertions(+), 22 deletions(-)

lib/std/mem.zig+31-22
......@@ -1911,7 +1911,7 @@ pub fn writePackedInt(comptime T: type, bytes: []u8, bit_offset: usize, value: T
19111911/// Any extra bytes in buffer after writing the integer are set to zero. To
19121912/// avoid the branch to check for extra buffer bytes, use writeIntLittle
19131913/// instead.
1914pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void {
1914fn writeIntSliceLittleNative(comptime T: type, buffer: []u8, value: T) void {
19151915 assert(buffer.len >= @divExact(@typeInfo(T).Int.bits, 8));
19161916
19171917 if (@typeInfo(T).Int.bits == 0) {
......@@ -1921,21 +1921,27 @@ pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void {
19211921 buffer[0] = @as(u8, @bitCast(value));
19221922 return;
19231923 }
1924 // TODO I want to call writeIntLittle here but comptime eval facilities aren't good enough
1925 const uint = std.meta.Int(.unsigned, @typeInfo(T).Int.bits);
1926 var bits = @as(uint, @bitCast(value));
1927 for (buffer) |*b| {
1928 b.* = @as(u8, @truncate(bits));
1929 bits >>= 8;
1930 }
1924
1925 const write_end = @divExact(@typeInfo(T).Int.bits, 8);
1926 @as(*align(1) T, @ptrCast(buffer)).* = value;
1927 @memset(buffer[write_end..], 0);
1928}
1929
1930fn writeIntSliceLittleForeign(comptime T: type, buffer: []u8, value: T) void {
1931 return writeIntSliceLittleNative(T, buffer, @byteSwap(value));
19311932}
19321933
1934pub const writeIntSliceLittle = switch (native_endian) {
1935 .Little => writeIntSliceLittleNative,
1936 .Big => writeIntSliceLittleForeign,
1937};
1938
19331939/// Writes a twos-complement big-endian integer to memory.
19341940/// Asserts that buffer.len >= @typeInfo(T).Int.bits / 8.
19351941/// The bit count of T must be divisible by 8.
19361942/// Any extra bytes in buffer before writing the integer are set to zero. To
19371943/// avoid the branch to check for extra buffer bytes, use writeIntBig instead.
1938pub fn writeIntSliceBig(comptime T: type, buffer: []u8, value: T) void {
1944fn writeIntSliceBigNative(comptime T: type, buffer: []u8, value: T) void {
19391945 assert(buffer.len >= @divExact(@typeInfo(T).Int.bits, 8));
19401946
19411947 if (@typeInfo(T).Int.bits == 0) {
......@@ -1946,25 +1952,28 @@ pub fn writeIntSliceBig(comptime T: type, buffer: []u8, value: T) void {
19461952 return;
19471953 }
19481954
1949 // TODO I want to call writeIntBig here but comptime eval facilities aren't good enough
1950 const uint = std.meta.Int(.unsigned, @typeInfo(T).Int.bits);
1951 var bits = @as(uint, @bitCast(value));
1952 var index: usize = buffer.len;
1953 while (index != 0) {
1954 index -= 1;
1955 buffer[index] = @as(u8, @truncate(bits));
1956 bits >>= 8;
1957 }
1955 const write_start = buffer.len - @divExact(@typeInfo(T).Int.bits, 8);
1956 @memset(buffer[0..write_start], 0);
1957 @as(*align(1) T, @ptrCast(buffer[write_start..])).* = value;
1958}
1959
1960fn writeIntSliceBigForeign(comptime T: type, buffer: []u8, value: T) void {
1961 return writeIntSliceBigNative(T, buffer, @byteSwap(value));
19581962}
19591963
1964pub const writeIntSliceBig = switch (native_endian) {
1965 .Little => writeIntSliceBigForeign,
1966 .Big => writeIntSliceBigNative,
1967};
1968
19601969pub const writeIntSliceNative = switch (native_endian) {
1961 .Little => writeIntSliceLittle,
1962 .Big => writeIntSliceBig,
1970 .Little => writeIntSliceLittleNative,
1971 .Big => writeIntSliceBigNative,
19631972};
19641973
19651974pub const writeIntSliceForeign = switch (native_endian) {
1966 .Little => writeIntSliceBig,
1967 .Big => writeIntSliceLittle,
1975 .Little => writeIntSliceBigForeign,
1976 .Big => writeIntSliceLittleForeign,
19681977};
19691978
19701979/// Writes a twos-complement integer to memory, with the specified endianness.