Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: unnecessary hash/eq functions for global arrays #30528

Open
dsnet opened this issue Mar 1, 2019 · 4 comments
Open

cmd/compile: unnecessary hash/eq functions for global arrays #30528

dsnet opened this issue Mar 1, 2019 · 4 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Performance
Milestone

Comments

@dsnet
Copy link
Member

dsnet commented Mar 1, 2019

This is a generalization of the problem described in #30449.

Suppose we have a unexported global variable:

var myArray [4]T

and none of the operations performed on this array:

  • let the array itself escape from the package (implies that the variable is unexported)
  • rely on comparability of the array (e.g., use of == or as a map key)

For example, operations like indexing (e.g., myArray[3]) and slicing (e.g., myArray[:]) are permitted.

If the above conditions are met, I believe that hash/eq functions need not be generated for that array since it is provably not used in the package, and cannot be used dynamically since the array itself does not escape from the package.


The use case for this is code like:

var globalMessageTypes [2]protoimpl.MesageType // Desire no hash/eq functions for this type

func (T) Type() protoreflect.MessageType {
    return &globalMessageTypes[0]
}

func (R) Type() protoreflect.MessageType {
    return &globalMessageTypes[1]
}

func init() {
    for i := range ... {
        globalMessageTypes[i] = ...
    }
}

We declare globalMessageTypes as an array so that the T.Type and R.Type methods do not need a bounds check when indexing into the global array. However, the generated hash/eq functions add significant binary bloat.

The workaround to this is to use a global slice instead of an array, but that has other issues (see #30529).

@bcmills bcmills added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Mar 2, 2019
@bcmills bcmills added this to the Unplanned milestone Mar 2, 2019
@cherrymui
Copy link
Member

However, the generated hash/eq functions add significant binary bloat.

Are you talking about the binary size of the executable? Or the object file? I would think the linker deadcode eliminates the hash/eq functions if they are not called.

@cherrymui
Copy link
Member

cherrymui commented Mar 2, 2019

That said, we probably should fix the compiler to not generate them in the first place.

@dsnet
Copy link
Member Author

dsnet commented Mar 3, 2019

Are you talking about the binary size of the executable? Or the object file?

Definitely object file, not sure about binary. The issue @neild and I were running into was that the linker was OOMing. There are many reasons for an OOM, but one contributor were (presumably) the size of the object file inputs, for which the hash/eq functions were a non-trivial contributor of bloat.

@josharian
Copy link
Contributor

@martisch

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jul 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Performance
Projects
None yet
Development

No branches or pull requests

5 participants