1. Better Way to Do This
- Posted by euphoric (admin) Aug 06, 2009
- 1163 views
Is there a standard lib or more efficient function that could replace this? I'm using this for a type definition. The variable needs to be all sequences.
function no_atoms( sequence s ) integer i = 1 for t=1 to length(s) do if atom(i) then return 0 end if end for return 1 end function
2. Re: Better Way to Do This
- Posted by bernie Aug 06, 2009
- 1144 views
- Last edited Aug 07, 2009
Is there a standard lib or more efficient function that could replace this? I'm using this for a type definition. The variable needs to be all sequences.
function no_atoms( sequence s ) integer i = 1 for t=1 to length(s) do if atom(i) then return 0 end if end for return 1 end function
Would this be faster ?
function no_atoms( sequence s ) integer i = length(s) while(sequence(s[i]) and i > 0 ) do i -= 1 end while if i = 0 then return 1 else return 0 end if end function
3. Re: Better Way to Do This
- Posted by jeremy (admin) Aug 06, 2009
- 1119 views
- Last edited Aug 07, 2009
I'm not sure which is faster, but wouldn't you want to make it a type? i.e. sequence_of_strings or something.
Jeremy
4. Re: Better Way to Do This
- Posted by DerekParnell (admin) Aug 06, 2009
- 1143 views
- Last edited Aug 07, 2009
Is there a standard lib or more efficient function that could replace this? I'm using this for a type definition. The variable needs to be all sequences.
function no_atoms( sequence s ) integer i = 1 for t=1 to length(s) do if atom(i) then return 0 end if end for return 1 end function
There is a Eu v4 library routine for this. It's in std/types.e
public type sequence_array( object x ) if not sequence(x) then return 0 end if for i = 1 to length(x) do if not sequence(x[i]) then return 0 end if end for return 1 end type
Note that this also allows empty sequences so if you must have at least one element you can use it like this ...
if length(S) and sequence_array(S) then ...
By the way, your code above wouldn't work as you don't update the 'i' variable.
5. Re: Better Way to Do This
- Posted by euphoric (admin) Aug 06, 2009
- 1113 views
- Last edited Aug 07, 2009
Is there a standard lib or more efficient function that could replace this? I'm using this for a type definition. The variable needs to be all sequences.
function no_atoms( sequence s ) integer i = 1 for t=1 to length(s) do if atom(i) then return 0 end if end for return 1 end function
There is a Eu v4 library routine for this. It's in std/types.e ... By the way, your code above wouldn't work as you don't update the 'i' variable.
Thanks Derek. I figured there was something already available. I also modified the code in browser before I submitted it, so it wasn't the original... just something I thought would be faster but didn't verify.
It was originally this:
function no_atoms( sequence s ) integer i = 1 for t=1 to length(s) do i = i and sequence(s[t]) end for return i end function
But I figured that would go through the entire sequence, so if there was an atom at s[1], why waste all that time? Of course, if the atom was at s[$], then no algorithm will get there faster. Right?
6. Re: Better Way to Do This
- Posted by euphoric (admin) Aug 06, 2009
- 1125 views
- Last edited Aug 07, 2009
Would this be faster ?
function no_atoms( sequence s ) integer i = length(s) while(sequence(s[i]) and i > 0 ) do i -= 1 end while if i = 0 then return 1 else return 0 end if end function
Yeah, that's faster all right! Here's the program I used to test the speeds. Bernie, your suggested code was waaaaaay faster than any other. It should definitely replace our std/lib sequence_array()!
include std/console.e atom t function no_atoms_1( sequence s ) integer i = 1 for t=1 to length(s) do if atom(s[t]) then return 0 end if end for return 1 end function function no_atoms_bernie_1( sequence s ) integer i = length(s) while sequence(s[i]) and i > 0 do i -= 1 end while if i=0 then return 1 else return 0 end if end function function no_atoms_bernie_2( sequence s ) integer i = length(s) while sequence(s[i]) and i > 0 do i -= 1 end while return not i end function function no_atoms_stdlib( object x ) if not sequence(x) then return 0 end if for i = 1 to length(x) do if not sequence(x[i]) then return 0 end if end for return 1 end function sequence a a = repeat({},500) a &= 1 t = time() for x=1 to 100000 do no_atoms_1( a ) end for ?time()-t t = time() for x=1 to 100000 do no_atoms_bernie_1( a ) end for ?time()-t t = time() for x=1 to 100000 do no_atoms_bernie_2( a ) end for ?time()-t for x=1 to 100000 do no_atoms_stdlib( a ) end for ?time()-t wait_key()
The no_atoms_bernie_2() was just my testing of the "not" thingie. Didn't help.
I do have a question. When i gets to zero, why doesn't the test for sequence(s[i]) fail? Or is 0 a valid sequence element?!
7. Re: Better Way to Do This
- Posted by Fernando Aug 06, 2009
- 1104 views
- Last edited Aug 07, 2009
Would this be faster ?
function no_atoms( sequence s ) integer i = length(s) while(sequence(s[i]) and i > 0 ) do i -= 1 end while if i = 0 then return 1 else return 0 end if end function
Yeah, that's faster all right! Here's the program I used to test the speeds. Bernie, your suggested code was waaaaaay faster than any other. It should definitely replace our std/lib sequence_array()!
include std/console.e atom t function no_atoms_1( sequence s ) integer i = 1 for t=1 to length(s) do if atom(s[t]) then return 0 end if end for return 1 end function function no_atoms_bernie_1( sequence s ) integer i = length(s) while sequence(s[i]) and i > 0 do i -= 1 end while if i=0 then return 1 else return 0 end if end function function no_atoms_bernie_2( sequence s ) integer i = length(s) while sequence(s[i]) and i > 0 do i -= 1 end while return not i end function function no_atoms_stdlib( object x ) if not sequence(x) then return 0 end if for i = 1 to length(x) do if not sequence(x[i]) then return 0 end if end for return 1 end function sequence a a = repeat({},500) a &= 1 t = time() for x=1 to 100000 do no_atoms_1( a ) end for ?time()-t t = time() for x=1 to 100000 do no_atoms_bernie_1( a ) end for ?time()-t t = time() for x=1 to 100000 do no_atoms_bernie_2( a ) end for ?time()-t for x=1 to 100000 do no_atoms_stdlib( a ) end for ?time()-t wait_key()
The no_atoms_bernie_2() was just my testing of the "not" thingie. Didn't help.
I do have a question. When i gets to zero, why doesn't the test for sequence(s[i]) fail? Or is 0 a valid sequence element?!
Probably, it's faster because in your example you put the atom at the end of the sequence, and Bernie's implementation begins from this point.
Depending on the uniformity of your sequences, it's possible to improve the speed if you store (cache) the index of the sequence when the function aborts. Then, on the next call, the circular search would begin at that stored point.
Regards,
Fernando
8. Re: Better Way to Do This
- Posted by DerekParnell (admin) Aug 06, 2009
- 1128 views
- Last edited Aug 07, 2009
Yeah, that's faster all right!
Sorry to burst the bubble, but the test is flawed.
Bernie's routines start from the back of the sequence and yours and mine from the front. Your test data had the atom as the last item so naturally, bernie's would find it first. Plus you forgot to reset the timer for the last test.
Here is some revised code.
include std/console.e atom t function no_atoms_1( sequence s ) integer i = 1 for t=1 to length(s) do if atom(s[t]) then return 0 end if end for return 1 end function function no_atoms_bernie_1( sequence s ) integer i = length(s) while sequence(s[i]) and i > 0 do i -= 1 end while if i=0 then return 1 else return 0 end if end function function no_atoms_bernie_2( sequence s ) integer i = length(s) while sequence(s[i]) and i > 0 do i -= 1 end while return not i end function function no_atoms_stdlib( sequence x ) for i = 1 to length(x) do if not sequence(x[i]) then return 0 end if end for return 1 end function sequence a -- Put atom in the middle. a = repeat({},250) & 1 & repeat({},250) t = time() for x=1 to 100000 do no_atoms_1( a ) end for ?time()-t t = time() for x=1 to 100000 do no_atoms_bernie_1( a ) end for ?time()-t t = time() for x=1 to 100000 do no_atoms_bernie_2( a ) end for ?time()-t t = time() for x=1 to 100000 do no_atoms_stdlib( a ) end for ?time()-t wait_key()
I get these results ...
c:\temp>eui test 0.5 0.641 0.656 0.469
I do have a question. When i gets to zero, why doesn't the test for sequence(s[i]) fail? Or is 0 a valid sequence element?!
Good question ... don't know the answer yet.
9. Re: Better Way to Do This
- Posted by euphoric (admin) Aug 06, 2009
- 1131 views
- Last edited Aug 07, 2009
Probably, it's faster because in your example you put the atom at the end of the sequence, and Bernie's implementation begins from this point.
Depending on the uniformity of your sequences, it's possible to improve the speed if you store (cache) the index of the sequence when the function aborts. Then, on the next call, the circular search would begin at that stored point.
DOH! I failed to understand that. Hmmmm.
Our standard lib function is the fastest it seems. Yay!
10. Re: Better Way to Do This
- Posted by euphoric (admin) Aug 06, 2009
- 1149 views
- Last edited Aug 07, 2009
Sorry to burst the bubble, but the test is flawed.
Thank you Derek and Fernando for your diligent coder brains and hawk-like eyes.
I do have a question. When i gets to zero, why doesn't the test for sequence(s[i]) fail? Or is 0 a valid sequence element?!
Good question ... don't know the answer yet.
I could understand if the test for i was first, because it would short circuit, right? Hmmmmm.
Take your time. You'll figure it out.
11. Re: Better Way to Do This
- Posted by SDPringle Aug 06, 2009
- 1126 views
- Last edited Aug 07, 2009
The tests do not blow up at the sequence test because you always put in an atom in the sequences you are testing. If you put a sequence in that contains no atoms your program will crash. Try passing in {""}
12. Re: Better Way to Do This
- Posted by LarryMiller Aug 06, 2009
- 1122 views
- Last edited Aug 07, 2009
Yeah, that's faster all right!
Sorry to burst the bubble, but the test is flawed.
Bernie's routines start from the back of the sequence and yours and mine from the front. Your test data had the atom as the last item so naturally, bernie's would find it first. Plus you forgot to reset the timer for the last test.
Here is some revised code.
include std/console.e atom t function no_atoms_1( sequence s ) integer i = 1 for t=1 to length(s) do if atom(s[t]) then return 0 end if end for return 1 end function function no_atoms_bernie_1( sequence s ) integer i = length(s) while sequence(s[i]) and i > 0 do i -= 1 end while if i=0 then return 1 else return 0 end if end function function no_atoms_bernie_2( sequence s ) integer i = length(s) while sequence(s[i]) and i > 0 do i -= 1 end while return not i end function function no_atoms_stdlib( sequence x ) for i = 1 to length(x) do if not sequence(x[i]) then return 0 end if end for return 1 end function sequence a -- Put atom in the middle. a = repeat({},250) & 1 & repeat({},250) t = time() for x=1 to 100000 do no_atoms_1( a ) end for ?time()-t t = time() for x=1 to 100000 do no_atoms_bernie_1( a ) end for ?time()-t t = time() for x=1 to 100000 do no_atoms_bernie_2( a ) end for ?time()-t t = time() for x=1 to 100000 do no_atoms_stdlib( a ) end for ?time()-t wait_key()
I get these results ...
c:\temp>eui test 0.5 0.641 0.656 0.469
I do have a question. When i gets to zero, why doesn't the test for sequence(s[i]) fail? Or is 0 a valid sequence element?!
Good question ... don't know the answer yet.
The answer is simple. i never reaches 0, the loop exits when i is 1. I discovered this when I changed the data to include only sequences. i then reached 0 and produced the usual error.
13. Re: Better Way to Do This
- Posted by euphoric (admin) Aug 06, 2009
- 1156 views
- Last edited Aug 07, 2009
The answer is simple. i never reaches 0, the loop exits when i is 1. I discovered this when I changed the data to include only sequences. i then reached 0 and produced the usual error.
Smarty pants. I'm going to bed now!
14. Re: Better Way to Do This
- Posted by bernie Aug 07, 2009
- 1146 views
Is there a standard lib or more efficient function that could replace this? I'm using this for a type definition. The variable needs to be all sequences.
function no_atoms( sequence s ) integer i = 1 for t=1 to length(s) do if atom(i) then return 0 end if end for return 1 end function
Would this be faster ?
function no_atoms( sequence s ) integer i = length(s) while(sequence(s[i]) and i > 0 ) do i -= 1 end while if i = 0 then return 1 else return 0 end if end function
Sorry I went to bed and realized I put the short-circuit wrong.
It should of been this:
function no_atoms( sequence s ) integer i = length(s) while( i > 0 and sequence(s[i]) ) do -- <----<< i -= 1 end while if i = 0 then return 1 else return 0 end if end function
[/quote]