google / google/built_value.dart

possible to copy already-computed memoized fields in build()?

Open
#774 9 comments 0 reactions 1 assignee Claimed by @davidmorgan View on GitHub
p2 / feature request
Dominant language
Dart
Stars
886
Forks
195
Avg merge
1d 11h
Merged PRs (30d)
4

Description

While profiling my application, I noticed that a supposedly memoized field was being recomputed over and over, even though the object's fields didn't change. However, the object itself changed through a call to `replace` (with identical field values as before).

The source of it seems to be that `build` does not copy the memoized fields.

I understand the danger here. Suppose we have

```dart
abstract class Value implements Built {
int get field;

@memoized
int get derived => field*2;

// boilerplate
}
var value = Value(field: 3);
print(value.derived); // prints 6
var builder = value.toBuilder();
builder.field = 30;
value = builder.build();
print(value.derived); // should print 60
```

If `build` naively copied the field `derived`, then it would still be the value 6 at the last print statement, even though we want it to be recomputed to be 60 since the non-derived `field` has changed.

Nonetheless, it would be great if the `ValueBuilder` class could detect whether any of its fields had changed since it was created, and if not, then any derived fields that have already been computed could be copied in `build` to avoid needing to re-compute them.

One way to do this would be to have `build` copy all of the derived fields by default, but for the writable field setters, on the first write to any of them, to set all the underlying derived fields to `null`. (in the example above, this would be the field named `__derived` in the generated .g.dart file). Or to be a bit more efficient, add to each `Builder` class a single `_dirty` field that's initially `false`, and is set to `true` when any setter is called, and `build()` only copies memoized fields into the new `Built` object if `_dirty == false`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.