Skip to content

Proposal: return value types in To*Node() to reduce allocations #29

@pwaller

Description

@pwaller

For sake of exposition I'm going to write in terms of the LLVM parser we're working on in llir/ll:

Please consider the ToLlvmNode function:

func ToLlvmNode(n *Node) LlvmNode {
	switch n.Type() {
	case ll.AShrExpr:
		return &AShrExpr{n}
	case ll.AShrInst:
		return &AShrInst{n}
	case ll.AddExpr:
[... many more elided ...]

At the moment, for parsing a large input with LLVM, this is one of the larger sources of allocations. (>30% of allocations from the parser) - see llir/llvm#55 for code to reproduce the measurement for yourself.

I note that the allocation can be completely eliminated by instead returning values of the node types (e.g, return AShrExpr{n}). This seems like a reasonable thing to do because all the node types do is embed a pointer to a node, and the value of the pointer doesn't ever need to be modified later, so it is fine to pass the pointer around by value. Because the node types structs only contain this pointer, they actually fit into the second value of the interface data, and therefore the returned value doesn't require an allocation either.

I did a brief experiment on the LLVM codebase a while back and observed about a 10% wall clock speedup and a significant reduction in allocations - giving (IIRC) a significant reduction in CPU and GC cost. The number of modifications I had to make to the LLIR parser was minimal.

I've run out of time for this moment. I intend to supply more (and more specific) details later, and perhaps a patch, if I get a spare moment. But for now I want to put this proposal out there and see what the response is.

For what it's worth I have some other tricks up my sleeve to reduce allocations, though they may be a bit too much of micro-optimization for some tastes. I'd be interested if you'd like to hear of these, but for now let's just consider this one which seems like the lowest hanging fruit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions