samber / mo

🦄 Monads and popular FP abstractions, powered by Go 1.18+ Generics (Option, Result, Either...)
https://pkg.go.dev/github.com/samber/mo
MIT License
2.47k stars 80 forks source link

Reorder fields to save more memory #1

Closed rbee3u closed 2 years ago

rbee3u commented 2 years ago

When size of T is not 8 bytes aligned, put isErr and value before err will save more memory

package main

import (
    "fmt"
    "unsafe"

    "github.com/samber/mo"
)

func Ok[T any](value T) Result[T] {
    return Result[T]{
        value: value,
        isErr: false,
    }
}

type Result[T any] struct {
    isErr bool
    value T
    err   error
}

func main() {
    fmt.Printf("mo(bool): %v\n", unsafe.Sizeof(mo.Ok[bool](false)))
    fmt.Printf("my(bool): %v\n", unsafe.Sizeof(Ok[bool](false)))
    fmt.Printf("mo(int8): %v\n", unsafe.Sizeof(mo.Ok[int8](0)))
    fmt.Printf("my(int8): %v\n", unsafe.Sizeof(Ok[int8](0)))
    fmt.Printf("mo(int16): %v\n", unsafe.Sizeof(mo.Ok[int16](0)))
    fmt.Printf("my(int16): %v\n", unsafe.Sizeof(Ok[int16](0)))
    fmt.Printf("mo(int32): %v\n", unsafe.Sizeof(mo.Ok[int32](0)))
    fmt.Printf("my(int32): %v\n", unsafe.Sizeof(Ok[int32](0)))
    fmt.Printf("mo(int64): %v\n", unsafe.Sizeof(mo.Ok[int64](0)))
    fmt.Printf("my(int64): %v\n", unsafe.Sizeof(Ok[int64](0)))
    fmt.Printf("mo(float32): %v\n", unsafe.Sizeof(mo.Ok[float32](0)))
    fmt.Printf("my(float32): %v\n", unsafe.Sizeof(Ok[float32](0)))
    fmt.Printf("mo(float64): %v\n", unsafe.Sizeof(mo.Ok[float64](0)))
    fmt.Printf("my(float64): %v\n", unsafe.Sizeof(Ok[float64](0)))
    fmt.Printf("mo(complex64): %v\n", unsafe.Sizeof(mo.Ok[complex64](0)))
    fmt.Printf("my(complex64): %v\n", unsafe.Sizeof(Ok[complex64](0)))
    fmt.Printf("mo(complex128): %v\n", unsafe.Sizeof(mo.Ok[complex128](0)))
    fmt.Printf("my(complex128): %v\n", unsafe.Sizeof(Ok[complex128](0)))
    fmt.Printf("mo([12]byte): %v\n", unsafe.Sizeof(mo.Ok[[12]byte]([12]byte{})))
    fmt.Printf("my([12]byte): %v\n", unsafe.Sizeof(Ok[[12]byte]([12]byte{})))
}

mo(bool): 32
my(bool): 24
mo(int8): 32
my(int8): 24
mo(int16): 32
my(int16): 24
mo(int32): 32
my(int32): 24
mo(int64): 32
my(int64): 32
mo(float32): 32
my(float32): 24
mo(float64): 32
my(float64): 32
mo(complex64): 32
my(complex64): 32
mo(complex128): 40
my(complex128): 40
mo([12]byte): 40
my([12]byte): 32
samber commented 2 years ago

Thanks for the suggestion.

Fixed.