Constant Constructors

30 views
Skip to first unread message

Chris Norman

unread,
Oct 7, 2021, 2:43:29 AM10/7/21
to mi...@dartlang.org
Hey folks,
I'm creating a library, which - as you might expect -- has lots of classes. Many of them only use final fields. Should I be creating constant constructors where possible? I had a Google, but there's only lots of stuff on how to create them, not whether or not they're preferred.

I thought over all constants were a bad idea, since they encourage globals, but from what I read here, it looks like I might actually be helping the Dart VM, which would presumably be a good thing.

Take care,

Chris Norman

Erik Ernst

unread,
Oct 7, 2021, 5:16:29 AM10/7/21
to mi...@dartlang.org
I think the links you already mentioned are very good sources of information on this topic, including the links from there such as Chris Strom's piece and Lasse's answer on https://japhr.blogspot.com/2012/12/dart-constant-constructors.html.

The main point is that a constant expression is generally evaluated at compile time and canonicalized, that is, even if your program has a thousand occurrences of `const C(42)` there will only be exactly one instance of `C` with the state produced by that list of actual constructor arguments.

The other side of that coin is that `identical(o1, o2)` can be true when `o1` and `o2` are two references to objects that are obtained as the value of constant expressions, whereas Dart (and other imperative & OO languages) otherwise guarantee that every object creation creates a fresh instance.

So you can save the time that you'd otherwise spend on creating new objects, but in return you have to make sure that it isn't a bug for your application that they will be the same object (so your application shouldn't rely on having `o1 != o2` as you'd have it for non-constants). This turns out to be a quite significant performance benefit in many situations, e.g., in Flutter applications when the set of pixels that need repainting in a new frame is computed.

Take care,

Chris Norman

--
For more ways to connect visit https://dart.dev/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/CANjhqb8wxpryf%2Bb1mD4KvznfaQaWw8v_VDm2bGkrVbeCU8rQaQ%40mail.gmail.com.


--
Erik Ernst  -  Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 København K, Denmark
CVR no. 28866984

Chris Norman

unread,
Oct 7, 2021, 5:25:40 AM10/7/21
to mi...@dartlang.org
On Thu, 7 Oct 2021 at 10:16, 'Erik Ernst' via Dart Misc <mi...@dartlang.org> wrote:
On Thu, Oct 7, 2021 at 8:43 AM 'Chris Norman' via Dart Misc <mi...@dartlang.org> wrote:
Hey folks,
I'm creating a library, which - as you might expect -- has lots of classes. Many of them only use final fields. Should I be creating constant constructors where possible? I had a Google, but there's only lots of stuff on how to create them, not whether or not they're preferred.

I thought over all constants were a bad idea, since they encourage globals, but from what I read here, it looks like I might actually be helping the Dart VM, which would presumably be a good thing.

I think the links you already mentioned are very good sources of information on this topic, including the links from there such as Chris Strom's piece and Lasse's answer on https://japhr.blogspot.com/2012/12/dart-constant-constructors.html.

The main point is that a constant expression is generally evaluated at compile time and canonicalized, that is, even if your program has a thousand occurrences of `const C(42)` there will only be exactly one instance of `C` with the state produced by that list of actual constructor arguments.

The other side of that coin is that `identical(o1, o2)` can be true when `o1` and `o2` are two references to objects that are obtained as the value of constant expressions, whereas Dart (and other imperative & OO languages) otherwise guarantee that every object creation creates a fresh instance.

So you can save the time that you'd otherwise spend on creating new objects, but in return you have to make sure that it isn't a bug for your application that they will be the same object (so your application shouldn't rely on having `o1 != o2` as you'd have it for non-constants). This turns out to be a quite significant performance benefit in many situations, e.g., in Flutter applications when the set of pixels that need repainting in a new frame is computed.

Hi Erik, thank you for your response.

So you're saying if I plan to keep an object around and there's nothing special about it (like the pixels you mentioned), give it a constant constructor. Otherwise, leave it alone?

Take care,

Chris Norman

--
For more ways to connect visit https://dart.dev/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/CANjhqb8wxpryf%2Bb1mD4KvznfaQaWw8v_VDm2bGkrVbeCU8rQaQ%40mail.gmail.com.


--
Erik Ernst  -  Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 København K, Denmark
CVR no. 28866984

--
For more ways to connect visit https://dart.dev/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.

Erik Ernst

unread,
Oct 7, 2021, 5:35:50 AM10/7/21
to mi...@dartlang.org
On Thu, Oct 7, 2021 at 11:25 AM 'Chris Norman' via Dart Misc <mi...@dartlang.org> wrote:

On Thu, 7 Oct 2021 at 10:16, 'Erik Ernst' via Dart Misc <mi...@dartlang.org> wrote:
On Thu, Oct 7, 2021 at 8:43 AM 'Chris Norman' via Dart Misc <mi...@dartlang.org> wrote:
Hey folks,
I'm creating a library, which - as you might expect -- has lots of classes. Many of them only use final fields. Should I be creating constant constructors where possible? I had a Google, but there's only lots of stuff on how to create them, not whether or not they're preferred.

I thought over all constants were a bad idea, since they encourage globals, but from what I read here, it looks like I might actually be helping the Dart VM, which would presumably be a good thing.

I think the links you already mentioned are very good sources of information on this topic, including the links from there such as Chris Strom's piece and Lasse's answer on https://japhr.blogspot.com/2012/12/dart-constant-constructors.html.

The main point is that a constant expression is generally evaluated at compile time and canonicalized, that is, even if your program has a thousand occurrences of `const C(42)` there will only be exactly one instance of `C` with the state produced by that list of actual constructor arguments.

The other side of that coin is that `identical(o1, o2)` can be true when `o1` and `o2` are two references to objects that are obtained as the value of constant expressions, whereas Dart (and other imperative & OO languages) otherwise guarantee that every object creation creates a fresh instance.

So you can save the time that you'd otherwise spend on creating new objects, but in return you have to make sure that it isn't a bug for your application that they will be the same object (so your application shouldn't rely on having `o1 != o2` as you'd have it for non-constants). This turns out to be a quite significant performance benefit in many situations, e.g., in Flutter applications when the set of pixels that need repainting in a new frame is computed.

Hi Erik, thank you for your response.

So you're saying if I plan to keep an object around and there's nothing special about it (like the pixels you mentioned), give it a constant constructor. Otherwise, leave it alone?

You might want to maintain a habit of declaring constant constructors in all those cases where it is possible (there are lots of reasons why any given expression may fail to be constant, and, consequently, lots of situations where any given constructor just can't be constant), and also using constant expressions where possible.

There is a space trade-off: If your application has a very large number of large constant objects then they will consume a lot of space at all times (unless it is statically known that they are never used, in which case they can be eliminated by tree shaking). If you were to allocate those same objects dynamically then the garbage collection might be able to keep your application smaller on average. But it's probably a good starting point to adopt as a general rule that "more constants is better".

Take care,

Chris Norman

--
For more ways to connect visit https://dart.dev/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/CANjhqb8wxpryf%2Bb1mD4KvznfaQaWw8v_VDm2bGkrVbeCU8rQaQ%40mail.gmail.com.


--
Erik Ernst  -  Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 København K, Denmark
CVR no. 28866984

--
For more ways to connect visit https://dart.dev/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/CACDCfDTd3fs7%3D8Fws2m2Z9NWfEmZiMF2gzTZ5WmCwKGkEbzXdg%40mail.gmail.com.

--
For more ways to connect visit https://dart.dev/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.

Chris Norman

unread,
Oct 7, 2021, 5:51:42 AM10/7/21
to mi...@dartlang.org
On Thu, 7 Oct 2021 at 10:35, 'Erik Ernst' via Dart Misc <mi...@dartlang.org> wrote:
On Thu, Oct 7, 2021 at 11:25 AM 'Chris Norman' via Dart Misc <mi...@dartlang.org> wrote:

On Thu, 7 Oct 2021 at 10:16, 'Erik Ernst' via Dart Misc <mi...@dartlang.org> wrote:
On Thu, Oct 7, 2021 at 8:43 AM 'Chris Norman' via Dart Misc <mi...@dartlang.org> wrote:
Hey folks,
I'm creating a library, which - as you might expect -- has lots of classes. Many of them only use final fields. Should I be creating constant constructors where possible? I had a Google, but there's only lots of stuff on how to create them, not whether or not they're preferred.

I thought over all constants were a bad idea, since they encourage globals, but from what I read here, it looks like I might actually be helping the Dart VM, which would presumably be a good thing.

I think the links you already mentioned are very good sources of information on this topic, including the links from there such as Chris Strom's piece and Lasse's answer on https://japhr.blogspot.com/2012/12/dart-constant-constructors.html.

The main point is that a constant expression is generally evaluated at compile time and canonicalized, that is, even if your program has a thousand occurrences of `const C(42)` there will only be exactly one instance of `C` with the state produced by that list of actual constructor arguments.

The other side of that coin is that `identical(o1, o2)` can be true when `o1` and `o2` are two references to objects that are obtained as the value of constant expressions, whereas Dart (and other imperative & OO languages) otherwise guarantee that every object creation creates a fresh instance.

So you can save the time that you'd otherwise spend on creating new objects, but in return you have to make sure that it isn't a bug for your application that they will be the same object (so your application shouldn't rely on having `o1 != o2` as you'd have it for non-constants). This turns out to be a quite significant performance benefit in many situations, e.g., in Flutter applications when the set of pixels that need repainting in a new frame is computed.

Hi Erik, thank you for your response.

So you're saying if I plan to keep an object around and there's nothing special about it (like the pixels you mentioned), give it a constant constructor. Otherwise, leave it alone?

You might want to maintain a habit of declaring constant constructors in all those cases where it is possible (there are lots of reasons why any given expression may fail to be constant, and, consequently, lots of situations where any given constructor just can't be constant), and also using constant expressions where possible.

There is a space trade-off: If your application has a very large number of large constant objects then they will consume a lot of space at all times (unless it is statically known that they are never used, in which case they can be eliminated by tree shaking). If you were to allocate those same objects dynamically then the garbage collection might be able to keep your application smaller on average. But it's probably a good starting point to adopt as a general rule that "more constants is better".

OK, that's just what I wanted to know. Thank you so much. 
Reply all
Reply to author
Forward
0 new messages