Advantage of const against static readonly?

C

cody

Iam wondering what the benefit of using const over static readonly is.

static readonly is a runtime constant and can be set once in the initializer
or the static ctor, whereas const is suffering from binary incompatibility
since it is hardbaked into the binary.

I do not believe there is a performance advantage with using const over
static readonly since the JIT will take account of that or am I wrong here?
 
M

Mattias Sjögren

One notable difference is that consts don't consume any memory at
runtime since they aren't loaded into memory.



Mattias
 
C

cody

You aren't worried about the memory consumption of a static readonly value
which exists exactly one time due to its static nature, are you :)
No the opposite is the case: If your const is a rather large struct it will
be hardbaked in each binary which uses this library.
I suspect that the JIT will generate both both const and static readonly
exactly the same code as I cannot imagine a reason why I would not be
possible to optimize the code this way.
 
J

Joakim Karlsson

A const's value must be valuated at compile time, whereas a readonly's
value can be set at runtime in the constructor of the class. This means
that a const can only be of any of the primitive types or a string,
whereas a readonly field can be of any type.

A readonly field can have different values assigned to it every time the
class is instantiated, a const field has the same value for every object
created.

/Joakim
 
M

Mattias Sjögren

You aren't worried about the memory consumption of a static readonly value
which exists exactly one time due to its static nature, are you :)

Not really, no. I'm just pointing out one of the differences. But the
effect could be quite real if you consider a large enum. If enums were
built on readonly static fields instead of consts you could probably
waste a few KB with "useless" static fields taking up memory.

No the opposite is the case: If your const is a rather large struct

You can't declare const structs. As Joakim wrote you can only have
consts of primitive types and string (plus any other reference type
but only with the value null).

I suspect that the JIT will generate both both const and static readonly
exactly the same code as I cannot imagine a reason why I would not be
possible to optimize the code this way.

While it can optimize use of the field, it can't "optimize away" the
storage location for the static field itself.



Mattias
 
C

cody

Joakim Karlsson said:
A const's value must be valuated at compile time, whereas a readonly's
value can be set at runtime in the constructor of the class. This means
that a const can only be of any of the primitive types or a string, whereas
a readonly field can be of any type.

I was looking for advantages of using const of static readonly I see there
are only advantages for using the latter as I suspectected.
A readonly field can have different values assigned to it every time the
class is instantiated, a const field has the same value for every object
created.

Iam talking about *static* readonly. But indeed it could have a different
value every time the program starts, but where is the disadvantage here?
 
C

cody

You aren't worried about the memory consumption of a static readonly value
Not really, no. I'm just pointing out one of the differences. But the
effect could be quite real if you consider a large enum. If enums were
built on readonly static fields instead of consts you could probably
waste a few KB with "useless" static fields taking up memory.

But enums *are* stored somewhere in the assembly there are declared in, or
did I misunderstood you? An Application will stop working if you would
remove the definition of the enum from the library it is using.
While it can optimize use of the field, it can't "optimize away" the
storage location for the static field itself.

Maybe but is the point here? As I poined out earlier you aren't worried
about the memory consumption of a static readonly value which exists exactly
one time :)

But I have indeed found one reason why const can be better than static
readonly field: Accessing a static readonly value forces the static
constructor of that class to run whereas this is not the case with const
values.
 
J

Joakim Karlsson

cody said:
I was looking for advantages of using const of static readonly I see there
are only advantages for using the latter as I suspectected.

Ah! Sorry. I guess I read that too fast :)
Iam talking about *static* readonly. But indeed it could have a different
value every time the program starts, but where is the disadvantage here?

In cases where you want to cache information that needs to be calculated
only once, i can see the usefulness. A stupid example: storing the time
the application started.

Regards,
Joakim
 
C

cody

I was looking for advantages of using const of static readonly I see
Ah! Sorry. I guess I read that too fast :)


In cases where you want to cache information that needs to be calculated
only once, i can see the usefulness. A stupid example: storing the time
the application started.

You read too fast again - I was asking for the disadvantage of static
readonly this time :)

However, I found one: Accessing a static readonly field forces the static
constructor to run whereas access to a const field doesn't. However I think
that running a static ctor which does nothing that initializing one field
one time in the program runs is not such a bad disadvantage..
 
M

Mattias Sjögren

But enums *are* stored somewhere in the assembly there are declared in
Sure.


An Application will stop working if you would
remove the definition of the enum from the library it is using.

Not necessarily, the const values are embedded in the consumer's IL
code. Unless you use Reflection on the enum type, you can remove all
its enum members and it should still work (there are obfuscation tools
that do this).



Mattias
 
J

Jon Shemitz

cody said:
I do not believe there is a performance advantage with using const over
static readonly since the JIT will take account of that or am I wrong here?

An instance readonly will be at an offset within the object, and so
the instructions that read it can use short forms, thus often
providing a performance advantage over a const.

Since a static readonly will always be at an offset within the global
data, the instructions have to use full global offsets (ie, 32 (or 64)
bits) and thus a 8 or 16-bit constant might actually be slightly
faster than a a 8 or 16-bit static readonly.
 
J

Jeff Louie

Cody.. const is preferred for version constants as they are compile time
constants and "can generate slightly more efficient code". readonly is
prefered otherwise as they are run time constants, are not limited to
{primitive types, enums and strings}, and are easier to maintain over
time.

"Effective C#" Bill Wagner

Regards,
Jeff
 
C

cody

An Application will stop working if you would
Not necessarily, the const values are embedded in the consumer's IL
code. Unless you use Reflection on the enum type, you can remove all
its enum members and it should still work (there are obfuscation tools
that do this).

Enum.Parse(), Enum.GetValues() and so on will stop working, but you are
right I can store any value that I want in a enum wheather the value is
defined in the enum or not.
 
C

cody

I do not believe there is a performance advantage with using const over
An instance readonly will be at an offset within the object, and so
the instructions that read it can use short forms, thus often
providing a performance advantage over a const.

Isn't every variable an offset in an object? And why should it be faster to
read a varaible from an object, while const is always stored inline thus
should be faster.
Since a static readonly will always be at an offset within the global
data, the instructions have to use full global offsets (ie, 32 (or 64)
bits) and thus a 8 or 16-bit constant might actually be slightly
faster than a a 8 or 16-bit static readonly.

Isn't every variable accessed by a 32bit address, be it a static, a readonly
or a normal instance variable? The only exceptions are local variables.
And what does the number of bits of a const have to do with that?
 
C

cody

Cody.. const is preferred for version constants as they are compile time
constants and "can generate slightly more efficient code". readonly is
prefered otherwise as they are run time constants, are not limited to
{primitive types, enums and strings}, and are easier to maintain over
time.

What is the point of "version constants"? Could you give an example where
this could actually be useful? Each Assembly knows exactly the versions of
every assembly which it references.
 
J

Jon Shemitz

cody said:
Isn't every variable an offset in an object?

Static variables are, in effect, global data. So, no, every variable
is NOT an offset within an object.
And why should it be faster to
read a varaible from an object, while const is always stored inline thus
should be faster.

It comes down to instruction length. MOV EAX,0x12345678 is a five or
six byte instruction. MOV EAX,[ESI+0x8] is a two or three byte
instruction. Instruction length is pretty much the biggest determinant
of execution speed.
Isn't every variable accessed by a 32bit address, be it a static, a readonly
or a normal instance variable? The only exceptions are local variables.

No. An offset within an object will typically use short instruction
forms.
And what does the number of bits of a const have to do with that?

Again, MOV AL,$12 is smaller and faster than MOV EAX,[$12345678].
 
C

cody

see comments inline
And why should it be faster to
read a varaible from an object, while const is always stored inline thus
should be faster.

It comes down to instruction length. MOV EAX,0x12345678 is a five or
six byte instruction. MOV EAX,[ESI+0x8] is a two or three byte
instruction. Instruction length is pretty much the biggest determinant
of execution speed.

I do not believe that. With the first instruction you already have the data
in the processor
internal instruction cache while the latter instruction needs to read from
system memory.
No. An offset within an object will typically use short instruction
forms.

Maybe, if you access the variable from the inside of the object a short form
can be used:

int i = this.MyReadonly; // MOV EAX,[ESI+0x??]

But from the outside you have to use the full address, IMHO:

int i = myObject.Myreadonly; // MOV EAX,[$????????]
And what does the number of bits of a const have to do with that?

Again, MOV AL,$12 is smaller and faster than MOV EAX,[$12345678].

IIRC a 32 bit processor will process calculations with 32 bit registers
as fast as or even faster than operations with say 8 bit operands, e.g:

mov al, 10

won't be faster than

mov eax, 10
 
J

Jon Shemitz

cody said:
I do not believe that.

Your privilege. Otoh, that's pretty much what I've seen in native code
systems, and I do more than my share of micro-benchmarking.
 
J

Jeff Louie

cody... the example given is marking a serialized object with a version
constant.

"Persistent values that mark specific versions should be compile time
constants, they never change. The current version should be a runtime
constant, changing with each release."
Effective C# Bill Wagner

Regards,
Jeff
What is the point of "version constants"? Could you give an example
where
this could actually be useful? Each Assembly knows exactly the versions
of
every assembly which it references.<
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top