i get to within a factor of 10 of the standard iterator. that's not
wonderful, i know, but looking at the generated code it doesn't appear to
understand that the parameters are integers (hence my comment above).
(but i am only guessing here, i don't really understand things that much).
here's the typed code - there are "Any" all over the place:
$(Expr(:lambda, {:r},
{{:n,:#s7,:#s6,:i},{{:r,TypedRange{Int64,Int64,Int64},0},{:n,Any,2},{:#s7,Any,2},{:#s6,(Any,Any),18},{:i,Any,18}},{}},
:(begin # /home/andrew/.julia/v0.3/IntModN/src/Range.jl, line 44:
n = 0 # line 45:
#s7 = Int64 - Int64
unless top(!)(top(done)(r::TypedRange{Int64,Int64,Int64},#s7)) goto
1
2:
#s6 = top(next)(r::TypedRange{Int64,Int64,Int64},#s7)::(Any,Any)
i = top(tupleref)(#s6::(Any,Any),1)
#s7 = top(tupleref)(#s6::(Any,Any),2) # line 46:
n = n + i
3:
unless top(!)(top(!)(top(done)(r::TypedRange{Int64,Int64,Int64},#s7)))
goto 2
1:
0: # line 48:
return n
end)))
conclusion so far is that the kind of "do it at compile time" hacks you can
do in c++ templates really don't carry across to julia.
andrew
On Friday, 21 March 2014 00:28:05 UTC-3, Jameson wrote:
>
> Yes, you would have to enforce that in the inner constructor for the type.
>
> What are you seeing for performance?
>
>
> On Thu, Mar 20, 2014 at 11:25 PM, andrew cooke <[email protected]<javascript:>
> > wrote:
>
>>
>> for the record, this almost works, once types are specified. what seems
>> to limit things is the lack (afaict) of a way to specify that the type
>> parameters are themselves Ints. for example
>>
>> start{S::Int,I::Int,E::Int}(r::TypedRange{S,I,E}) = S - I
>>
>> is invalid syntax.
>>
>> andrew
>>
>>
>>
>> On Wednesday, 19 March 2014 18:44:05 UTC-3, andrew cooke wrote:
>>>
>>>
>>> ok, after thinking some, i guess it's because the type of the iterator
>>> isn't fixed by the function arguments. i'll see if i can make that
>>> happen. andrew
>>>
>>> On Wednesday, 19 March 2014 18:03:09 UTC-3, andrew cooke wrote:
>>>>
>>>>
>>>> various people (mainly vtjnash, i guess) have repeatedly warned me off
>>>> using the type system as much as i would like. despite this, i had the
>>>> idea of sticking iterator parameters into the type system. my reasoning
>>>> was that specialised code would be inlined for each iterator. it failed
>>>> miserably (gave a 300x slowdown), but i don't understand why.
>>>>
>>>> so can anyone give me a rough sketch of why the code at
>>>> https://github.com/andrewcooke/IntModN.jl/blob/master/src/Range.jl is
>>>> such a bad idea?
>>>>
>>>> here's the meat:
>>>>
>>>> immutable TypedRange{S,I,E} <: Ranges{Int}
>>>> end
>>>>
>>>> # MyInt is used just to isolate this code; if I re-implement the generic
>>>> # count I cause chaos, changing code deep within the implementation...
>>>>
>>>> function colon(start::MyInt, inc::MyInt, end_::MyInt)
>>>> TypedRange{start.i, inc.i, end_.i}()
>>>> end
>>>>
>>>>
>>>> start{S,I,E}(r::TypedRange{S,I,E}) = S - I
>>>> next{S,I,E}(r::TypedRange{S,I,E}, i::Int) = (i + I, i + I)
>>>> done{S,I,E}(r::TypedRange{S,I,E}, i::Int) = I > 0 ? i >= E : i <= E
>>>>
>>>> thanks,
>>>> andrew
>>>>
>>>>
>