Skip to content

Fixes from @albrow's Wasm review #148

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

Merged
merged 2 commits into from
Sep 24, 2019
Merged

Fixes from @albrow's Wasm review #148

merged 2 commits into from
Sep 24, 2019

Conversation

nhooyr
Copy link
Contributor

@nhooyr nhooyr commented Sep 23, 2019

@nhooyr
Copy link
Contributor Author

nhooyr commented Sep 23, 2019

Some discussion at 82db14a#r35201593

websocket_js.go Outdated
defer c.readBufMu.Unlock()

me := c.readBuf[0]
c.readBuf = c.readBuf[1:]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this approach is fast, I think it doesn't allow the GC to free the associated memory since the underlying array still contains every element. This is different from bytes.Buffer which does attempt to recover/free memory when possible. See https://golang.org/src/bytes/buffer.go?s=9451:9501#L286.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GC should be fine as when a new message arrives, the slice will be appended to and the old slice thrown away. I'll even nil it out immediately to make sure GC knows the message event isn't necessary anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is different from bytes.Buffer which does attempt to recover/free memory when possible. See https://golang.org/src/bytes/buffer.go?s=9451:9501#L286.

Not sure what you're referring to here. *bytes.Buffer never attempts to free/recover memory afaik.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was referring to these lines in bytes.Buffer.Read:

if b.empty() {
	// Buffer is empty, reset to recover space.
	b.Reset()
	if len(p) == 0 {
		return 0, nil
	}
	return 0, io.EOF
}

I suppose "free" is not the right word since the memory is held and reused by the buffer. b.Reset is called in few other places in the implementation too.

What I meant to draw attention to is that just because the old slice is thrown away doesn't mean the underlying array is. Just looking at the line c.readBuf = c.readBuf[1:] made me concerned that we might be holding on to every element in the underlying array indefinitely. However, you're right that this is not the case because of the use of append. The memory associated with the underlying array will be freed if append causes the slice to grow (at which point the remaining data is copied to a new underlying array). This probably happens fairly often so it should be fine.

It's still true that bytes.Buffer has some memory optimizations (e.g., calling Reset when possible in order to reuse memory) that aren't present here but it might not be a big deal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have fixed this anyway in my latest commit. c.readBuf is now fixed size at whatever the limit is set (right now 32) and elements are shifted around instead of slicing the array to avoid allocations.

defer c.readBufMu.Unlock()

me := c.readBuf[0]
copy(c.readBuf, c.readBuf[1:])
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm.. this version requires fewer memory allocations but it also calls copy on every read. I'm curious if this has any impact on performance? It might be fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't expect it to be a problem. Copying data is very fast, especially since we're only copying pointers to the data.

@nhooyr
Copy link
Contributor Author

nhooyr commented Sep 24, 2019

Fixed all of the issues you've pointed out @albrow. Please review again.

@nhooyr nhooyr merged commit 433c00d into master Sep 24, 2019
@nhooyr nhooyr deleted the fix-review branch September 24, 2019 18:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants