Understanding iterators and inlining

90 views
Skip to first unread message

Lea Hayes

unread,
Aug 22, 2013, 3:54:07 PM8/22/13
to haxe...@googlegroups.com
Hey guys

So out of curiosity I decided to look at the C++ output for the following block of code and was pleasantly surprised at its efficiency:

var list:Vector<Cell> = generateList();
for (cell in list) {
}

When looking at the generated C++ source, there doesn't appear to be any trace of an iterator instance. I was expecting to see an instance of an iterator class!

Here is an abridged version of the generated source:

int _g = (int)0;
Array< ::Dynamic > _g1 = generateList();
while (((_g < _g1->__Field(HX_CSTRING("length"), true)))) {
   
++(_g);
}

This certainly seems more efficient than what I was expecting! I still need to dig into the __Field(HX_CSTRING(... part to find out what is actually happening there.

Upon initial inspection, integer iterators appear to be more efficient:

var list = generateList();
for (i in 0...list.length) {
}

producing something like:

Array< ::Dynamic > _g1 = generateList();
int _g2 = (int)0;
int _g = _g1->cellText->__Field(HX_CSTRING("length"),true);
while (((_g2 < _g))) {
   
int i = (_g2)++;
}

Q1. Where is the iterator object?

Q2. Has the entire class somehow been inlined?

Q3. Can non-iterator classes be inlined in a similar way thus effectively avoiding actual instantiation?

Just to clarify, I am not looking to optimise any code right now. I am just curious as to what is going on under the hood :P

TopHattedCoder

unread,
Aug 22, 2013, 5:36:03 PM8/22/13
to haxe...@googlegroups.com
1) Inline constructors can move the fields of a class to local variables.
2) Yes, it's only simple so apparently Haxe had no trouble.
3) Yes, with inline constructors. Just make sure your class is simple enough to be inlined.
For example:
import haxe.io.*;
class Test {
   
static function main() {
       
for(i in new BetterIntIter(10, 20, 2))
            trace
(i);
   
}
}
class BetterIntIter {
   
var curr:Int;
   
var max:Int;
   
var jump:Int;
   
public inline function new(from:Int, to:Int, jump:Int = 1) {
       
this.curr = from;
       
this.max = to;
       
this.jump = jump;
   
}
   
public inline function hasNext():Bool
       
return curr < max;
   
public inline function next():Int
       
return curr += jump;
}
Is generated into the following Javascript:
(function () { "use strict";
var Test = function() { }
Test.main = function() {
   
var _g_curr = 10, _g_max = 20, _g_jump = 2;
   
while(_g_curr < _g_max) {
       
var i = _g_curr += _g_jump;
        console
.log(i);
   
}
}
Test.main();
})();
Just make sure every method you want to use is inlined.

Lea Hayes

unread,
Aug 22, 2013, 7:44:17 PM8/22/13
to haxe...@googlegroups.com
Fantastic explanation, thanks! :D

Jason O'Neil

unread,
Aug 22, 2013, 8:35:51 PM8/22/13
to haxe...@googlegroups.com

+1 for coolness... I didn't know about this trick

--
To post to this group haxe...@googlegroups.com
http://groups.google.com/group/haxelang?hl=en
---
You received this message because you are subscribed to the Google Groups "Haxe" group.
For more options, visit https://groups.google.com/groups/opt_out.
Reply all
Reply to author
Forward
0 new messages