Re: non-constant error for module AAs

2011-01-25 Thread Lars T. Kyllingstad
On Mon, 24 Jan 2011 10:45:03 -0500, Andrej Mitrovic wrote:

 Is this a bug?
 
 import std.stdio;
 
 string[string] values = [abc:abc, def:def];
 
 void main()
 {
 string[string] values2 = [abc:abc, def:def];
 }
 
 
 test.d(3): Error: non-constant expression [abc:abc,def:def]
 
 What's non-constant about that expression?


My guess would be that using an AA literal is just syntax sugar for 
calling an AA construction function, and that said function isn't 
CTFEable.

When you specify an initial value for a global, that value must be a 
compile-time constant.  If it's not, as in this case, the correct thing 
to do is to use a module constructor:

  string[string] values;
  static this()
  {
  values = [ abc:abc, def:def ];
  }

It is ONLY a good idea to use an enum array if you know you will be doing 
all lookups at compile time.  If the key you're looking for is just known 
at run time, the AA will be constructed anew for each lookup (I think), 
which is hideously expensive.

  enum string[string] values = [ abc:def, ghi:jkl ];

  // This is fine, because it is done at compile time.
  // It's essentially the same as:  auto s = def;
  auto s = values[abc];

  // This is a no-no, because it evaluates to something
  // like:  auto aa = values; auto s = aa[key];
  auto key = abc;
  auto s = values[key];

Here's an example program that demonstrates the difference.  On my 
machine, the enum AA version takes 22x longer than the normal AA 
version.


import std.datetime, std.stdio;


enum string[string] enumAA = [ abc : abc, def : def ];

string[string] normalAA;
static this()
{
normalAA = [ abc : abc, def : def ];
}


void main()
{
enum max = 10_000_000;
StopWatch sw;
string lookup1 = abc;
string lookup2 = def;

sw.start();
foreach (i; 0 .. max)
{
auto a = enumAA[lookup1];
auto b = enumAA[lookup2];
}
sw.stop();
writeln(sw.peek().seconds);

sw.reset();

sw.start();
foreach (i; 0 .. max)
{
auto a = normalAA[lookup1];
auto b = normalAA[lookup2];
}
sw.stop();
writeln(sw.peek().seconds);
}


Re: non-constant error for module AAs

2011-01-25 Thread spir

On 01/25/2011 08:54 AM, bearophile wrote:

Andrej Mitrovic:


It's interesting that enum works but immutable doesn't. enum will do, Thanks.


But there are some problems with enum AAs. Take a look at this little program:

enum int[int] aa = [1:2, 3:4];
int foo(int x) {
 return aa[x];
}
void main() {}


And the asm of foo():

_D4test3fooFiZi comdat
 pushEAX
 mov ECX,offset FLAT:_D10TypeInfo_i6__initZ
 mov EDX,offset FLAT:_D12TypeInfo_Hii6__initZ
 pushEAX
 push4
 pushECX
 push4
 push3
 push2
 push1
 push2
 pushEDX
 callnear ptr __d_assocarrayliteralT
 add ESP,018h
 pushEAX
 callnear ptr __aaGetRvalue
 mov EAX,[EAX]
 add ESP,010h
 pop ECX
 ret

Bye,
bearophile


IIUC, the compiler re-defines the constant (enum) AA at use point. Why?

Denis
--
_
vita es estrany
spir.wikidot.com



Re: non-constant error for module AAs

2011-01-25 Thread spir

On 01/25/2011 09:13 AM, Lars T. Kyllingstad wrote:

On Mon, 24 Jan 2011 10:45:03 -0500, Andrej Mitrovic wrote:


Is this a bug?

import std.stdio;

string[string] values = [abc:abc, def:def];

void main()
{
 string[string] values2 = [abc:abc, def:def];
}


test.d(3): Error: non-constant expression [abc:abc,def:def]

What's non-constant about that expression?



My guess would be that using an AA literal is just syntax sugar for
calling an AA construction function, and that said function isn't
CTFEable.

When you specify an initial value for a global, that value must be a
compile-time constant.  If it's not, as in this case, the correct thing
to do is to use a module constructor:

   string[string] values;
   static this()
   {
   values = [ abc:abc, def:def ];
   }

It is ONLY a good idea to use an enum array if you know you will be doing
all lookups at compile time.  If the key you're looking for is just known
at run time, the AA will be constructed anew for each lookup (I think),
which is hideously expensive.

   enum string[string] values = [ abc:def, ghi:jkl ];

   // This is fine, because it is done at compile time.
   // It's essentially the same as:  auto s = def;
   auto s = values[abc];

   // This is a no-no, because it evaluates to something
   // like:  auto aa = values; auto s = aa[key];
   auto key = abc;
   auto s = values[key];

Here's an example program that demonstrates the difference.  On my
machine, the enum AA version takes 22x longer than the normal AA
version.


import std.datetime, std.stdio;


enum string[string] enumAA = [ abc : abc, def : def ];

string[string] normalAA;
static this()
{
 normalAA = [ abc : abc, def : def ];
}


void main()
{
 enum max = 10_000_000;
 StopWatch sw;
 string lookup1 = abc;
 string lookup2 = def;

 sw.start();
 foreach (i; 0 .. max)
 {
 auto a = enumAA[lookup1];
 auto b = enumAA[lookup2];
 }
 sw.stop();
 writeln(sw.peek().seconds);

 sw.reset();

 sw.start();
 foreach (i; 0 .. max)
 {
 auto a = normalAA[lookup1];
 auto b = normalAA[lookup2];
 }
 sw.stop();
 writeln(sw.peek().seconds);
}


Waow, thank you, Lars, /this/ is an explanation.
Now, why doesn't D make an enum aa a normal variable like your normal aa (but 
evaluated at compile-time instead of import time)?


Normal
--
_
vita es estrany
spir.wikidot.com



non-constant error for module AAs

2011-01-24 Thread Andrej Mitrovic
Is this a bug?

import std.stdio;

string[string] values = [abc:abc, def:def];

void main()
{
string[string] values2 = [abc:abc, def:def];
}


test.d(3): Error: non-constant expression [abc:abc,def:def]

What's non-constant about that expression?


Re: non-constant error for module AAs

2011-01-24 Thread spir

On 01/24/2011 04:45 PM, Andrej Mitrovic wrote:

Is this a bug?

import std.stdio;

string[string] values = [abc:abc, def:def];

void main()
{
 string[string] values2 = [abc:abc, def:def];
}


test.d(3): Error: non-constant expression [abc:abc,def:def]

What's non-constant about that expression?


Had the same issue, and yop, it's a bug, and filed: search the issue tracker.

Denis
--
_
vita es estrany
spir.wikidot.com



Re: non-constant error for module AAs

2011-01-24 Thread Andrej Mitrovic
On 1/24/11, BlazingWhitester max.kl...@gmail.com wrote:
 On 2011-01-24 17:45:03 +0200, Andrej Mitrovic said:

 Is this a bug?

 import std.stdio;

 string[string] values = [abc:abc, def:def];

 void main()
 {
 string[string] values2 = [abc:abc, def:def];
 }


 test.d(3): Error: non-constant expression [abc:abc,def:def]

 What's non-constant about that expression?

 It's because of D's implementation of AA, but you can make it work with
 enum, e.g. enum string[string] values = [abc:abc, def:def]; //
 works just fine at compile time



It's interesting that enum works but immutable doesn't. enum will do, Thanks.


Re: non-constant error for module AAs

2011-01-24 Thread bearophile
Andrej Mitrovic:

 It's interesting that enum works but immutable doesn't. enum will do, Thanks.

But there are some problems with enum AAs. Take a look at this little program:

enum int[int] aa = [1:2, 3:4];
int foo(int x) {
return aa[x];
}
void main() {}


And the asm of foo():

_D4test3fooFiZi comdat
pushEAX
mov ECX,offset FLAT:_D10TypeInfo_i6__initZ
mov EDX,offset FLAT:_D12TypeInfo_Hii6__initZ
pushEAX
push4
pushECX
push4
push3
push2
push1
push2
pushEDX
callnear ptr __d_assocarrayliteralT
add ESP,018h
pushEAX
callnear ptr __aaGetRvalue
mov EAX,[EAX]
add ESP,010h
pop ECX
ret

Bye,
bearophile