Hello,
I just started dabbling with ATS, so bear with me.
I really like using datatypes / datavtypes as a control structure, but the allocation / deallocation rates seem fairly high when there are a fair number created in sequence.
I suppose I've gotten used to the stream-fusion motif in Haskell. I'm aware of the caveats of directly translating from one language to another (eg, optimizations like stream-fusion may not hold, nor are they necessary, per se), but I like the idea of the enum-based state machine. For example:
datatype Step (s:t@ype, a:t@ype) =
| Yield of (s,a)
| Step of (s)
| Done
When I do something like, say, generate 1000000 of these guys, my allocation / deallocation rates are pretty high, and I suspect it's impacting performance (eg, relative performance with -O2: a stack-only version with unboxed tuple "Step" runs in 11ms, a datavtype version runs in closer to 35ms, getting 44ms-60ms with GC and datatypes, while a naive shot in Haskell runs in 9ms).
I could use something like this, but it is much less elegant (this is how I implemented the stack-only version):
datatype StepType =
| Yield
| Skip
| Done
typedef Step (s:t@ype, a:t@ype) = @(StepType,s,a)
I'm wondering if it's possible to do any of the following (or if ATS might already be doing it for me):
a.) Statically allocate a single variable of a given datatype, and/or create the datatype at a specific memory location
b) Define an initial heap size that stays constant throughout the lifetime of a program, so that transient entities like the ones above consistently re-use the same memory pool.
I think I could probably conjure up something like the latter using custom allocation functions (eg, DATS_MEMALLOC_USER), but I thought I would reach out first...