Determine if Day of the Week is during the weekend

vefatica

I'm still at it! I'm using func=`0` to compute a "baseline" (overhead) time which is subtracted from all the times. IMHO, this gives a more meaningful comparison of the various functions. Below, notice the difference in the pairs of functions I=6,7 and I=8,9. It's the difference between a numeric comparison and a string comparison (and it's significant). Quoting gives a string comparison, apparently saving the conversion of the parameters to numbers (and, since the strings in question are one character long, the comparison goes pretty quickly).

Code:
``````                                        TIME IN SECONDS
I  FUNCTION                               GROSS   NET
0  `0`                                    1.297  0.000
1  `%@instr[%1,1,01000001]`               1.396  0.099
2  `%@index[17,%1,0]`                     1.390  0.093
3  `%@regex[[17],%1]`                     1.403  0.106
4  `%@eval[1-(301 MOD %1)]`               1.669  0.372
5  `%@eval[abs(%1-4)\3]`                  1.718  0.421
6  `%@if[%1==1 .OR. %1==7,1,0]`           1.840  0.543
7  `%@if["%1"=="1" .OR. "%1"=="7",1,0]`   1.555  0.258
8  `%@if[%@eval[%1 mod 6] == 1,1,0]`      1.937  0.640
9  `%@if["%@eval[%1 mod 6]" == "1",1,0]`  1.771  0.474``````

Kachupp

I'd of thought numeric version would be faster, but clearly its not

Did you see any difference in times from your stream load version to the in code version?
with your new Zero function

I don't understand why on my end the stream version is 10th of a sec slower. In time spent fishing it means nothing, but weirdly in formula One its the difference of 1st / 2nd place
Code:
``````Timing 10,000 iterations, each with a random (1-7) weekday ...Incode Functions

function fatica4 `%@instr[%1,1,01000001]`           1.444 s
function kachupp `%@index[17,%1,0]`                 1.455 s
function fatica2 `%@eval[1-(301 MOD %1)]`           2.003 s
function fatica3 `%@eval[abs(%1-4)\3]`              2.143 s
function fatica1 `%@if[%1==1 .OR. %1==7,1,0]`       2.336 s
function caverly `%@if[%@eval[%1 mod 6] == 1,1,0]`  2.417 s
function fatica5 `%@regex[[17],%1]`                 1.496 s

Wed 16/03/22  8:21
j:\dba>d3test.btm

Timing 10,000 iterations, each with a random (1-7) weekday ..Stream Load

function fatica4 `%@instr[%1,1,01000001]`           1.546 s
function kachupp `%@index[17,%1,0]`                 1.546 s
function fatica2 `%@eval[1-(301 MOD %1)]`           2.102 s
function fatica3 `%@eval[abs(%1-4)\3]`              2.248 s
function fatica1 `%@if[%1==1 .OR. %1==7,1,0]`       2.440 s
function caverly `%@if[%@eval[%1 mod 6] == 1,1,0]`  2.521 s
function fatica5 `%@regex[[17],%1]`                 1.589 s``````

Last edited:

vefatica

I'd of thought numeric version would be faster, but clearly its not
Internally, TCC is all Unicode strings. So anything that has to be treated as a number must be turned into a number (no doubt a floating point number).
Did you see any difference in times from your stream load version to the in code version?
with your new Zero function
As well as I can tell, no.

I changed things further.

The stream now looks like this.

Code:
```````0`
`%@instr[%1,1,01000001]`
`%@index[17,%1,0]`
`%@regex[[17],%1]`
`%@eval[1-(301 MOD %1)]`
`%@eval[abs(%1-4)\3]`
`%@if[%1==1 .OR. %1==7,1,0]`
`%@if["%1"=="1" .OR. "%1"=="7",1,0]`
`%@if[%@eval[%1 mod 6] == 1,1,0]`
`%@if["%@eval[%1 mod 6]" == "1",1,0]```````

I'm defining the function like this.

Code:
``````do line in @%0:functions.btm
if "%line" == "" goto done
setdos /x-47
echos %@format[-3,%@dec[%_do_loop]]%@format[-37,%line]^s^s
setdos /x+47
function func=%line``````

and calling it like this.

Code:
``%@func[%@random[1,7]]``

I also threw in an optional test to show that the functions are workung correctly (or not).

The latest BTM is attached. Sorry! It's back to using NOOP and _PERFCOUNT.

vefatica

The BTM didn't attach. I'll try a ZIP version.

Attachments

• dowtest.zip
691 bytes · Views: 59

Kachupp

the stream didn't get through, no worries I have a copy

vefatica

the stream didn't get through, no worries I have a copy
I wondered if it would and figured if it didn't you'd copy it from post #33 above.

Kachupp

This versions clearly quicker than previous dowtest.btm version with your plugin's

Code:
``````                                        TIME IN SECONDS
I  FUNCTION                               GROSS   NET
0  `0`                                    1.103  0.000
1  `%@instr[%1,1,01000001]`               1.239  0.136
2  `%@index[17,%1,0]`                     1.240  0.137
3  `%@regex[[17],%1]`                     1.271  0.168
4  `%@eval[1-(301 MOD %1)]`               1.626  0.523
5  `%@eval[abs(%1-4)\3]`                  1.704  0.601
6  `%@if[%1==1 .OR. %1==7,1,0]`           1.878  0.775
7  `%@if["%1"=="1" .OR. "%1"=="7",1,0]`   1.397  0.294
8  `%@if[%@eval[%1 mod 6] == 1,1,0]`      1.987  0.884
9  `%@if["%@eval[%1 mod 6]" == "1",1,0]`  1.775  0.672``````

vefatica

NOOP only makes a tiny difference vs. ECHO>NUL. And @MRAND is no faster than @RANDOM (but it has more options). The `unset * & unalias * & unfunction *` can help a lot in any BTM that you want to be fast and doesn't rely on system/user environment variables. In particular, if you have any UDF's defined, `unfunction *` makes it easier to resolve the name "@FUNC" (which has to be done 10000 times per test).

Kachupp

All my altered version of your scripts are all un-set/alias/function before I run them just for a clean measure. I really like the last one, it out performs all with as you say meaningful comparison.

All the information gathered is going to help me with my small analytical engine project

Thanks Vince!

vefatica

I also re-did the test.

Code:
``````v:\> dowtest.btm test

Except for function 0, about 28.6% of outcomesare expected to be 1

0  `0`                                     0.0% are 1
1  `%@instr[%1,1,01000001]`               28.5% are 1
2  `%@index[17,%1,0]`                     28.7% are 1
3  `%@regex[[17],%1]`                     28.6% are 1
4  `%@eval[1-(301 MOD %1)]`               29.2% are 1
5  `%@eval[abs(%1-4)\3]`                  28.6% are 1
6  `%@if[%1==1 .OR. %1==7,1,0]`           29.7% are 1
7  `%@if["%1"=="1" .OR. "%1"=="7",1,0]`   28.3% are 1
8  `%@if[%@eval[%1 mod 6] == 1,1,0]`      28.3% are 1
9  `%@if["%@eval[%1 mod 6]" == "1",1,0]`  28.7% are 1``````

Kachupp

I saw this a couple of days ago with my 00101001 comment. I wonder at the time that this might affect the timings. So I started a image text file with 50/50 split of zero and one that my tests would read as a standard even mixed it up 010101 ,, 00110011 etc at the time I thought this standard linear condition couldn't be a method for testing as the results would be and are way lower than the random method so I dismissed it. Because weekdays only become random if you're on drugs or alcohol which I gave up nearly 30 yrs ago after 3rd driving conviction

vefatica

Aha! You gave me an idea. I've been using @RANDOM[1,7] bacause it returns the various values of _dowi randomly, but each with probability 1/7. But with such a large number of tries, there's no real need for them to appear randomly; they might as well appear in order 12345671234567...

So new question: How can I generate the sequence 1234567 over and over again QUICKLY.

Having considered that for a whole minute or two, my first idea is %@char[%@eval[49+(%_do_loop MOD 7)]]. I doubt that will be faster than %@RANDOM[1,7]

Kachupp

set t_range=1234567

vefatica

set t_range=1234567
Huh? You've lost me.

I did a little testing. Using %@func[1] instead of %@func[%@random[1,7]] seemed to take about 0.01 sec off each of the times if I can measure it correctly. Normal run-to-run variation is more than that.

To get 10,000 I tried

Code:
``do j=1 to 1429 (do i=1 to 7 ( noop %@func[%i] ))``

That definitely made things worse by more than 0.2 sec.

Kachupp

Ignore that dense set t_range, To many windows flying in and out, need a snack

For the my test purposes; 010010, the other day I just changed the test range @random[1,2]

Do we need to even test for 7 .. @mrand[1,2] same results without all the @dowi possible responses outcome is faster and I believe still accurate as a speed test.

Last edited:

Kachupp

Vince I've added my bruteforce routine to you script it feeds 1 2 3 4 5 6 7 to the functions via @fileread once for as many iterations as you give it from the prompt. Your test routine has been
commented out just the text is echoed.

Code:
``````setlocal
on break (timer /q off & quit)

unfunction *
unset *
unalias *

%@if["%1" == "",set auto=200,set auto=%1]

: # create image file bruteforce

set open_1=%@fileopen[dowi_image.txt,w,b]

do %auto
set w=%@filewriteb[%open_1,14, 1 2 3 4 5 6 7]
enddo

(    set tcate=%@truncate[%open_1]
set jmp=%@fileseek[%open_1,0,0]
set close=%@fileclose[%open_1]
)

echo # __N = %@len[%read]

rem iff "%1" != "test" then
echo ^r^nTiming %__N iterations, each force feed (1 2 3 4 5 6 7) days
echo The functon at index 0 gives an estimate of the "overhead", time
echo that's common to all tests.  It's subtracted from the gross time
echo to get the net time, a (hopefully) better comparison.^r^n
echo %@repeat[ ,39]TIME IN SECONDS
echo I  FUNCTION%@repeat[ ,31]GROSS    NET
rem endiff

do line in @%0:functions.btm
if "%line" == "" goto done
setdos /x-47
echos %@format[-3,%@dec[%_do_loop]]%@format[-37,%line]^s^s
setdos /x+47
function func=%line

rem iff "%1" == "test" then
rem     do i=1 to 25 (echos %@func[%@mrand[1,2]])
rem     echo.
rem     iterate
rem endiff

set t0=%_perfcount

rem do i=1 to %__N (noop %@func[%@mrand[1,2]])
do i=1 to %__N (noop %@func[%read])
set t1=%_perfcount
set t=%@eval[(%t1-%t0)/%_perffreq=3]
if %_do_loop == 1 set overhead=%t
echo %t  %@eval[%t - %overhead=3]
enddo

:done
timer /q off
endlocal``````

Last edited:

vefatica

I don't understand. You're doing `do i=1 to %__N (noop %@func[%read])`. But doesn't %read contain the whole string from the file? It seems you want to be using @INSTR (or something to pick one character out of %read). ... ???

vefatica

I'm going to give up trying to beat @RANDOM[1,7]. Since Rex seeds the generator for @RANDOM and I seed the generator for @MRAND, the only thing that's done to generate the next random number is (after getting the value of x from an in-memory array)

Code:
``````    x ^= (x >> 29) & 0x5555555555555555ULL;
x ^= (x << 17) & 0x71D67FFFEDA60000ULL;
x ^= (x << 37) & 0xFFF7EEE000000000ULL;
x ^= (x >> 43);
return x;``````

For those who don't know "C", that's 4 bitwise XORs, 4 bitwise shifts, and 3 bitwise ANDs ... lightning fast stuff, all built into the processor.

I even wrote a plugin ...

Code:
``````v:\> help @cyclic

@CYCLIC[start,period] ... set start and period and return start+period-1; defaults: 0,2
@CYCLIC[]             ... return the next number in the cyclic sequence start,start+1,...,start+period-1

v:\> noop %@cyclic[1,7] & do i=1 to 10 ( echos %@cyclic[] )
1234567123
v:\>``````

It's pretty spartan but when I used `%func[%@cyclic[]]` in place of `%func[%@random[1,7]]` it did nothing to the times.

Kachupp

Sorry Vince, Short Answer Yes, Long Answer I'm older than I was yesterday my eyes are sore I'm an idiot when tired and hungry. 2 functions give dreaded divide by zero functions 3 & 9

change these
Code:
``````set w=%@filewriteb[%open_1,7,1234567]
:
do i=0 to %__N (noop %@func[%@instr[%i,1,%read]])``````

dcantor

I use this function:
Code:
``function weekend=`%@if[%@left[1,%@dow[%1]] eq S,1,0]```