Skip to content

Commit

Permalink
update examples after feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
jonbodner committed Aug 5, 2020
1 parent 18a987a commit 8be37cb
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 47 deletions.
31 changes: 23 additions & 8 deletions data/main.go
@@ -1,7 +1,9 @@
package main

import (
"encoding/binary"
"fmt"
"math/bits"
"unsafe"
)

Expand All @@ -12,28 +14,41 @@ type Data struct {
// padded with 1 byte to make it align
}

var isLE bool

func init() {
var x uint16 = 0xFF00
xb := *(*[2]byte)(unsafe.Pointer(&x))
isLE = (xb[0] == 0x00)
}

func DataFromBytesUnsafe(b [16]byte) Data {
return *(*Data)(unsafe.Pointer(&b))
data := *(*Data)(unsafe.Pointer(&b))
if isLE {
data.Value = bits.ReverseBytes32(data.Value)
}
return data
}

func DataFromBytes(b [16]byte) Data {
d := Data{}
d.Value = uint32(b[3])<<24 + uint32(b[2])<<16 + uint32(b[1])<<8 + uint32(b[0])
d.Value = binary.BigEndian.Uint32(b[:4])
copy(d.Label[:], b[4:14])
d.Active = b[14] != 0
return d
}

func BytesFromDataUnsafe(d Data) [16]byte {
return *(*[16]byte)(unsafe.Pointer(&d))
if isLE {
d.Value = bits.ReverseBytes32(d.Value)
}
b := *(*[16]byte)(unsafe.Pointer(&d))
return b
}

func BytesFromData(d Data) [16]byte {
out := [16]byte{}
out[3] = byte(d.Value >> 24)
out[2] = byte(d.Value >> 16)
out[1] = byte(d.Value >> 8)
out[0] = byte(d.Value)
binary.BigEndian.PutUint32(out[:4], d.Value)
copy(out[4:14], d.Label[:])
if d.Active {
out[14] = 1
Expand All @@ -49,7 +64,7 @@ func main() {
copy(d.Label[:], "Phone")
fmt.Println(d, unsafe.Alignof(d), unsafe.Alignof(d.Value), unsafe.Alignof(d.Label), unsafe.Alignof(d.Active))

b := [16]byte{237, 95, 132, 0, 80, 104, 111, 110, 101, 0, 0, 0, 0, 0, 1, 0}
b := [16]byte{0, 132, 95, 237, 80, 104, 111, 110, 101, 0, 0, 0, 0, 0, 1, 0}
fmt.Println(b)

b1 := BytesFromData(d)
Expand Down
26 changes: 13 additions & 13 deletions data/main_test.go
Expand Up @@ -7,53 +7,53 @@ import (
var bh [16]byte
var dh Data

var input = [16]byte{237, 95, 132, 0, 80, 104, 111, 110, 101, 0, 0, 0, 0, 0, 1, 0}
var input = [16]byte{0, 132, 95, 237, 80, 104, 111, 110, 101, 0, 0, 0, 0, 0, 1, 0}

var inputData = Data {
Value:8675309,
Label: [10]byte{80, 104, 111, 110, 101, 0, 0, 0, 0, 0},
var inputData = Data{
Value: 8675309,
Label: [10]byte{80, 104, 111, 110, 101, 0, 0, 0, 0, 0},
Active: true,
}

func TestIdentical(t *testing.T) {
b1 := BytesFromData(inputData)
b2 := BytesFromDataUnsafe(inputData)
if b1 != b2 {
t.Fatal(b1,b2)
t.Fatal(b1, b2)
}
if b1 != input {
t.Fatal(b1,input)
t.Fatal(b1, input)
}
d1 := DataFromBytes(b1)
d2 := DataFromBytesUnsafe(b1)
if d1 != d2 {
t.Fatal(d1,d2)
t.Fatal(d1, d2)
}
if d1 != inputData {
t.Fatal(d1,inputData)
t.Fatal(d1, inputData)
}
}

func BenchmarkBytesFromData(b *testing.B) {
for i := 0;i<b.N;i++ {
for i := 0; i < b.N; i++ {
bh = BytesFromData(inputData)
}
}

func BenchmarkBytesFromDataUnsafe(b *testing.B) {
for i := 0;i<b.N;i++ {
for i := 0; i < b.N; i++ {
bh = BytesFromDataUnsafe(inputData)
}
}

func BenchmarkDataFromBytes(b *testing.B) {
for i := 0;i<b.N;i++ {
for i := 0; i < b.N; i++ {
dh = DataFromBytes(input)
}
}

func BenchmarkDataFromBytesUnsafe(b *testing.B) {
for i := 0;i<b.N;i++ {
for i := 0; i < b.N; i++ {
dh = DataFromBytesUnsafe(input)
}
}
}
15 changes: 7 additions & 8 deletions numbers/main.go
Expand Up @@ -7,20 +7,19 @@ import (

func main() {
var i64 int64 = 1_000_000
i64ptr := uintptr(unsafe.Pointer(&i64))
bytes := *(*[unsafe.Sizeof(i64)]byte)(unsafe.Pointer(i64ptr))
i64ptr := unsafe.Pointer(&i64)
bytes := *(*[unsafe.Sizeof(i64)]byte)(i64ptr)
fmt.Println(bytes)
i32 := *(*int32)(unsafe.Pointer(i64ptr))
i32 := *(*int32)(i64ptr)
fmt.Println(i32)

i64ptr += 4
bytesShifted := *(*[unsafe.Sizeof(i64)]byte)(unsafe.Pointer(i64ptr))
i64ptrShifted := unsafe.Pointer(uintptr(unsafe.Pointer(&i64)) + 4)
bytesShifted := *(*[unsafe.Sizeof(i64)]byte)(i64ptrShifted)
fmt.Println(bytesShifted)

i32Shifted := *(*int32)(unsafe.Pointer(i64ptr))
i32Shifted := *(*int32)(unsafe.Pointer(&bytesShifted))
fmt.Println(i32Shifted)

i64Shifted := *(*int64)(unsafe.Pointer(i64ptr))
i64Shifted := *(*int64)(unsafe.Pointer(&bytesShifted))
fmt.Println(i64Shifted)
}

13 changes: 7 additions & 6 deletions string_modification1/main.go
Expand Up @@ -8,17 +8,18 @@ import (

func main() {
s := "hello"
sHdrData := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&s)).Data)
sHdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
fmt.Println(sHdr.Len) // prints 5

for i :=0;i< sHdr.Len; i++ {
bp := *(*byte)(unsafe.Pointer(sHdr.Data+uintptr(i)))
fmt.Println(string(bp))
for i := 0; i < sHdr.Len; i++ {
bp := *(*byte)(unsafe.Pointer(uintptr(sHdrData) + uintptr(i)))
fmt.Print(string(bp))
}
sHdr.Len = sHdr.Len+10
fmt.Println()
sHdr.Len = sHdr.Len + 10
fmt.Println(s)

bp := (*byte)(unsafe.Pointer(sHdr.Data+2))
bp := (*byte)(unsafe.Pointer(uintptr(sHdrData) + 2))
*bp = *bp + 1
fmt.Println(s)
}
13 changes: 1 addition & 12 deletions string_modification2/main.go
Expand Up @@ -8,19 +8,8 @@ import (

func main() {
s := "hello"
sHdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
fmt.Println(sHdr.Len) // prints 5

for i :=0;i< sHdr.Len; i++ {
bp := *(*byte)(unsafe.Pointer(sHdr.Data+uintptr(i)))
fmt.Print(string(bp))
}
fmt.Println()

sHdr.Len = sHdr.Len+10
fmt.Println(s)

b := []byte("goodbye")
sHdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
bHdr := (*reflect.SliceHeader)(unsafe.Pointer(&b))
sHdr.Data = bHdr.Data
sHdr.Len = bHdr.Len
Expand Down

0 comments on commit 8be37cb

Please sign in to comment.