GithubHelp home page GithubHelp logo

dkorunic / betteralign Goto Github PK

View Code? Open in Web Editor NEW
480.0 8.0 11.0 214 KB

Make your Go programs use less memory (maybe)

License: BSD 3-Clause "New" or "Revised" License

Go 100.00%
alignment analyzer golang memory garbage-collector

betteralign's Introduction

betteralign

GitHub license GitHub release

About

betteralign is a tool to detect structs that would use less memory if their fields were sorted and optionally sort such fields.

This is a fork of an official Go fieldalignment tool and vast majority of the alignment code has remained the same. There are however some notable changes:

  • skips over generated files, either files with known "generated" suffix (_generated.go, _gen.go, .gen.go, .pb.go, .pb.gw.go) or due to package-level comment containing Code generated by... DO NOT EDIT. string,
  • skips over test files (files with _test.go suffix),
  • skips over structs marked with comment betteralign:ignore,
  • doesn't lose comments (field comments, doc comments, floating comments or otherwise) but the comment position heuristics is still work in progress,
  • does very reliable atomic file I/O with strong promise not to corrupt and/or lose contents upon rewrite (not on Windows platform),
  • has more thorough testing in regards to expected optimised vs golden results,
  • integrates better with environments with restricted CPU and/or memory resources (Docker containers, K8s containers, LXC, LXD etc).

Retaining comments has been done with using DST (Decorated Syntax Tree) with decorating regular AST. Sadly when using DST we cannot use "fix" mode with SuggestedFixes, but we have to print whole DST to retain decorations.

In case you are wondering why DST and not AST, in general sense AST does not associate comments to nodes, but it holds fixed offsets. Original fieldalignment tool just erases all struct/field/floating comments due to this issue and while there is a CL with a possible fix, it's still a work in progress as of this time.

Note, this is a single-pass analysis tool and sorting all structs optimally might require more than one pass.

Let us also mention original projects handling this task and without which this derivative work wouldn't exist in the first place:

Installation

There are two ways of installing betteralign:

Manual:

Download your preferred flavor from the releases page and install manually, typically to /usr/local/bin/betteralign

Using go install:

go install github.com/dkorunic/betteralign/cmd/betteralign@latest

Usage

betteralign: find structs that would use less memory if their fields were sorted

Usage: betteralign [-flag] [package]

Flags:
  -apply
    	apply suggested fixes
  -generated_files
    	also check and fix generated files
  -test_files
    	also check and fix test files

To get all recommendations on your project:

betteralign ./...

To automatically fix your project files, while ignoring test and generated files:

betteralign -apply ./...

It is possible to include generated files and test files by enabling generated_files and/or test_files flags.

Star history

Star History Chart

betteralign's People

Contributors

dependabot[bot] avatar dkorunic avatar marselester avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

betteralign's Issues

`betteralign:ignore` not working

Tried versions both 0.3.1 and 0.3.2

I have a struct that I am trying to ignore. I have tried to comment it in multiple ways -

//betteralign:ignore
type MyStruct struct {
	Ts         time.Time    `json:"ts"`
	Val        float64      `json:"val"`
	MetricID   int64        `json:"metricId"`
	EntityID   int64        `json:"entityId"`
	Tags       pgtype.JSONB `json:"tags"`
	Parameters pgtype.JSONB `json:"parameters"`
}
// betteralign:ignore
type MyStruct struct {
	Ts         time.Time    `json:"ts"`
	Val        float64      `json:"val"`
	MetricID   int64        `json:"metricId"`
	EntityID   int64        `json:"entityId"`
	Tags       pgtype.JSONB `json:"tags"`
	Parameters pgtype.JSONB `json:"parameters"`
}
type MyStruct struct {
	// betteralign:ignore
	Ts         time.Time    `json:"ts"`
	Val        float64      `json:"val"`
	MetricID   int64        `json:"metricId"`
	EntityID   int64        `json:"entityId"`
	Tags       pgtype.JSONB `json:"tags"`
	Parameters pgtype.JSONB `json:"parameters"`
}

And each time, the library reorders the struct.

Use stable sorting function

Why not use stable sort for struct fields?

  • Less comments would get misplaced
  • The semantic ordering of fields would be often preserved:
// something like
type before struct {
	topBool    bool
	string1    string
	string2    string
	string3    string
	bottomBool bool
}
// sometimes turns into
type after_bad struct {
	string2    string
	string1    string
	string3    string
	topBool    bool
	bottomBool bool
}
// when we can have
type after_good struct {
	string1    string
	string2    string
	string3    string
	topBool    bool
	bottomBool bool
}

The fix is like five keystrokes, but I'll attach a PR.

Thanks for your work btw, great tool!

Stats of the memory optimised

Understanding the metrics is crucial, especially when there is a noticeable enhancement. This request is for the inclusion of a feature that would add details regarding the percentage or quantity of memory optimized after the execution of the betteralign ./... command. Such information would contribute to a more comprehensive assessment of the impact and effectiveness of the optimization process.

Incorrect size calculation?

Given the code:

type structB struct {
	b uint8
	a net.IP
}

betteralign suggests to realign:

% betteralign ./...
/tmp/tmp.RrY2d8UsZv/main.go:14:14: struct with 16 pointer bytes could be 8

However, that makes no difference:

size of *main.structA = 32
size of *main.structB = 32

`betteralign -apply` command returning exit code 3

Description:

I am using the betteralign tool to align the code in my project automatically. When I run the command betteralign -apply ./... in my project CI, the tool successfully aligns the code, but it returns an exit code of 3, which causes my CI to fail.

Expected behaviour:

I expect betteralign to return an exit code of 0 when it successfully aligns my code with the -apply flag.

`betteralign -apply` command returning exit code 3

Description:

I am using the betteralign tool to align the code in my project automatically. When I run the command betteralign -apply ./... in my project CI, the tool successfully aligns the code, but it returns an exit code of 3, which causes my CI to fail.

Expected behaviour:

I expect betteralign to return an exit code of 0 when it successfully aligns my code with the -apply flag.

New sorted struct is not applied to inline structs

First of all thank you for your work on this! I noticed something that I'm not sure this tool will be able to address but thought I would bring this up. I have an easy way to reproduce the "issue".

package main

import "net/http"

type MyStruct struct {
	Handler  http.HandlerFunc
	Method   string
	Pattern  string
	SomeUint uint16
	Resource string
}

func main() {
	register("3", MyStruct{
		func(w http.ResponseWriter, r *http.Request) {
			w.WriteHeader(http.StatusOK)
		},
		http.MethodPost,
		"pattern",
		0,
		"resource",
	})
}

func register(version string, m MyStruct) error {
	return nil
}

The problem being that MyStruct gets optimally sorted but the inline struct maintains the previous order of fields which I then have to fix manually. Feel free to close this out if it's not something we can address, I might also take a look tonight and see if it's doable but wanted to let you know first.

go install fails

I am on windows running the command and getting the following error:

go install github.com/dkorunic/betteralign/cmd/betteralign@latest
# github.com/dkorunic/betteralign
..\..\go\pkg\mod\github.com\dkorunic\[email protected]\betteralign.go:519:21: undefined: renameio.WriteFile
..\..\go\pkg\mod\github.com\dkorunic\[email protected]\betteralign.go:519:60: undefined: renameio.IgnoreUmask

Command help - `-fix` flag is documented but doesn't do anything

Cool tool. I found the fieldalignment tool unsuitable for general purpose use (e.g. as a core part of the build). So far, this resolves the qualms I had, so thanks.

I'm guessing there's a reason you made it -apply rather than -fix, but just thought I'd raise that -fix is also documented, but doesn't seem to do anything. I tried -fix first, for whatever reason.

$ betteralign -h
betteralign: find structs that would use less memory if their fields were sorted

Usage: betteralign [-flag] [package]

This analyzer find structs that can be rearranged to use less memory, and provides
a suggested edit with the most compact order.

Note that there are two different diagnostics reported. One checks struct size,
and the other reports "pointer bytes" used. Pointer bytes is how many bytes of the
object that the garbage collector has to potentially scan for pointers, for example:

        struct { uint32; string }

have 16 pointer bytes because the garbage collector has to scan up through the string's
inner pointer.

        struct { string; *uint32 }

has 24 pointer bytes because it has to scan further through the *uint32.

        struct { string; uint32 }

has 8 because it can stop immediately after the string pointer.

Be aware that the most compact order is not always the most efficient.
In rare cases it may cause two variables each updated by its own goroutine
to occupy the same CPU cache line, inducing a form of memory contention
known as "false sharing" that slows down both goroutines.


Flags:
  -V    print version and exit
  -all
        no effect (deprecated)
  -apply
        apply suggested fixes
  -c int
        display offending line with this many lines of context (default -1)
  -cpuprofile string
        write CPU profile to this file
  -debug string
        debug flags, any subset of "fpstv"
  -fix
        apply all suggested fixes
  -flags
        print analyzer flags in JSON
  -generated_files
        also check and fix generated files
  -json
        emit JSON output
  -memprofile string
        write memory profile to this file
  -source
        no effect (deprecated)
  -tags string
        no effect (deprecated)
  -test
        indicates whether test files should be analyzed, too (default true)
  -test_files
        also check and fix test files
  -trace string
        write trace log to this file
  -v    no effect (deprecated)

convert app to use as package

i'm very interesting to reuse you code to align my files after it generated, do you plan to change code to be able to use as package?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.