ecodeclub / eorm

简单 ORM 框架
Apache License 2.0
194 stars 64 forks source link

Buffer pool #22

Closed flycash closed 2 years ago

flycash commented 3 years ago

English Only

Please check existing issues first to avoid duplication and answer the questions below before submitting your issue.

Use case(s)

When we are building a query, we can use strings.Builder. But in fact, we should think about reuse the buffer to avoid GC and improve the performance.

Usually, we will use sync.Pool to cache the buffer. But there is a problem that the buffer's capacity may be expanded when it was put back.

For example, the original capacity of buffer is 128, and it means that we can only store 128 bytes. However, we reuse this buffer to build a long query which has more than 128 bytes, e.g. 200 bytes, and then the buffer capacity was expanded to 256 bytes.

If most of the queries only need 50 bytes, it means that we waste a lot memory. A typical solution is avoiding cache big buffer.

Proposed Solution

(Please describe your proposed design/solution, if any)

Alternatives Considered

(Other possible options for solving the problem?)

Additional Context

(Paste any relevant logs - please use code blocks (```) to format console output, logs, and code as it's very hard to read otherwise.)

(If you can, link to the line of code that might be helpful to explain the context)

flycash commented 3 years ago

I think we may need multiple pools. For example, one of them store the buffer < 128 bytes, another stores 128-1024 bytes. If we use one pool, all the buffer in this pool finally will be expanded to the limitation. For example, if we do not store the buffer > 256bytes, all the buffer in this pool are possibly expanded to 256 bytes..

Codexiaoyi commented 3 years ago

I think we may need multiple pools. For example, one of them store the buffer < 128 bytes, another stores 128-1024 bytes. If we use one pool, all the buffer in this pool finally will be expanded to the limitation. For example, if we do not store the buffer > 256bytes, all the buffer in this pool are possibly expanded to 256 bytes..

Yes, I think it's necessary. The first version could simply divide pools. In the builder.go file, we return the Query struct, so do we include the size of Args in the calculation? Maybe we can cache the Query.

flycash commented 3 years ago

We don't need to think about the size of Args. We only take SQL into consideration.

Codexiaoyi commented 3 years ago

We are currently using bytebufferpool to complete memory reuse. With issue #39 .