mass confusion on MASK

The help for MASK says that for ‘c’, then one or more positions are checked for c. But is c strictly alpha? What if I say: if blah = MASK(‘99’)? Am I asking it to search for 99 in the first two positions or anywhere in blah?

MASK is positional. To look for a string within a variable, use SCAN.

IF  #VAR = SCAN '99'     /* Does 99 exist within #VAR?

No, that’s not true. MASK can be positional and not positional, too. To look for ‘99’ in a string, you can use mask, too. And you can use it more efficient than SCAN, like in:

IF #VAR = MASK(*'99') /* Does 99 exist within #VAR?
IF #VAR = MASK('99') /* Does #VAR bgin with '99'?
IF #VAR = MASK(*'99'/) /* Does #VAR end with '99'?

MASK indeed is nearly as powerful as regular expressions, but not that complicated (in my opinion).

[quote="Wilfried B

No argument, the wild card additions to MASK give it a lot more capability than SCAN.

However, in terms of performance, for the functionality that SCAN was designed for, SCAN is far more efficient than MASK.

For example;

DEFINE DATA LOCAL
1 #LOOP (P9)
1 #STRING (A20)
1 #CPU-TIME (P9)
1 #CPU-START (P9)
END-DEFINE
*
INCLUDE AATITLER
INCLUDE AASETC
*
MOVE CPU-TIME TO #CPU-START
SETA. SETTIME
FOR #LOOP = 1 TO 500000
IF #STRING = MASK (
‘X’)
IGNORE
END-IF
END-FOR
COMPUTE #CPU-TIME = *CPU-TIME - #CPU-START
WRITE 5T ‘MASK TIME’ *TIMD (SETA.) 5X #CPU-TIME
*
MOVE *CPU-TIME TO #CPU-START
SETB. SETTIME
FOR #LOOP = 1 TO 500000
IF #STRING = SCAN (‘X’)
IGNORE
END-IF
END-FOR
COMPUTE #CPU-TIME = *CPU-TIME - #CPU-START
WRITE 5T ‘SCAN TIME’ *TIMD (SETB.) 5X #CPU-TIME
*
END
PAGE # 1 DATE: Feb 14, 2007
PROGRAM: SCAN01 LIBRARY: SYSTEM

MASK TIME       49            489
SCAN TIME       39            388

SCAN is about 20 % faster and uses 25 % less CPU time.

If there was an X in the first position of #STRING, the output is:

PAGE #   1                    DATE:    Feb 14, 2007
PROGRAM: SCAN03               LIBRARY: SYSTEM

MASK TIME       36            355
SCAN TIME       35            345

The times above are on my PC; will run mainframe times later today (snowing, hailing and raining outside, so will stay in and play on the computer).

steve

Okay, it’s later.

Mainframe numbers are very interesting.

First, here are the numbers with no X

MASK TIME 19 112
SCAN TIME 9 61

The SCAN is twice as fast as the MASK.

With an X in the first position, the numbers are

MASK TIME 9 61
SCAN TIME 9 61

So, if the functionality you are looking for requires “searching” for a text string anywhere in an alpha variable, use SCAN, not MASK.

steve

Getting back to the original question:

IF #STRING = MASK(‘AB’)

will look for AB in positions 1 and 2

IF #STRING = MASK(??‘AB’)

will look for AB in positions 3 and 4

? . _ can all be used to indicate "skip a single position

  • % are the “wildcard” (any number of characters) characters

On the PC (mainframe results later) MASK (??‘XX’) is slightly faster (2%) than SCAN, however CPU time is 10% faster than SCAN.

steve

Your test on Solaris:

MASK TIME       56            562
SCAN TIME       47            468

But you can make it much more faster if you use an I4-field as a loop counter… :wink:

MASK TIME       29            282
SCAN TIME       19            195

Anyway: SCAN is slightly faster