BINARY (COMP or COMP-4)

BINARY data and synonyms COMP and COMP-4 are the two's complement data representation in COBOL.

BINARY data is declared with a PICTURE clause as with internal or external decimal data but the underlying data representation is as a halfword (2 bytes), a fullword (4 bytes) or a doubleword (8 bytes).

The compiler option TRUNC(OPT | STD | BIN) determines if and how the compiler corrects values back to the declared picture clause and how much significant data is present when accessing a data item.

Although the overall general performance considerations for BINARY data and the TRUNC option from V4 and earlier versions still apply in V6, some of the relative performance differences for the various TRUNC suboptions have changed (sometimes dramatically). These changes may impact coding and compiler option choices.

To quantify the relative and absolute performance differences a series of addition operations on binary data items were executed in a loop on a z13® machine. The 4 tests below contain the same type and number of arithmetic operations but have a varying number of digits. All of the operands are signed.

  • TEST 1: 8 additions with one each of 1 through 8 digits
  • TEST 2: 8 additions each with 9 digits
  • TEST 3: 8 additions with one each of 10 through 17 digits
  • TEST 4: 8 additions each with 18 digits

The tests were then compiled varying the TRUNC option.

The first experiment specified the TRUNC(STD) compiler option.

TRUNC(STD) instructs the compiler to always correct back to the specified PICTURE clause and allows the compiler to assume that loaded values only have the specified number of PICTURE clause digits.

Table 1. Performance differences results of four test cases when specifying TRUNC(STD)
TRUNC(STD) V4 versus TEST 1 V6 versus TEST 1 V6 versus V4
TEST 1: 1-8 digits 100% 100% 16.6%
TEST 2: 9 digits 145.9% 116.9% 13.3%
TEST 3: 10-17 digits 479.1% 116.4% 4%
TEST 4: 18 digits 768.2% 100.5% 2.2%
These results demonstrate that:
  • V6 outperforms V4 for all lengths when using TRUNC(STD).
  • Although performance slows as the number of digits increases for both V4 and V6 it slows much more gradually and to much lower overall amount using V6 compared to V4.

The second experiment specified the TRUNC(BIN) compiler option. Specifying this option is equivalent to using the COMP-5 type for all BINARY data.

TRUNC(BIN) instructs the compiler to allow values to only correct back to the underlying data representation (two, four or eight bytes) instead of back to the specified PICTURE clause. This option also requires the compiler to assume that loaded values can have up to two, four or eight bytes worth of significant data.

Table 2. Performance differences results of four test cases when specifying TRUNC(BIN)
TRUNC(BIN) V4 versus TEST 1 V6 versus TEST 1 V6 versus V4
TEST 1: 1-8 digits 100% 100% 62.5%
TEST 2: 9 digits 154.5% 100.4% 40.6%
TEST 3: 10-17 digits 5098.2% 1925.5% 23.6%
TEST 4: 18 digits 5099.2% 1928% 23.6%
These results demonstrate that:
  • V6 also outperforms V4 for all lengths when using TRUNC(BIN).
  • V6 shows no slow down when testing at 9 digits.
  • There is a dramatic reduction in performance for both V4 and V6 (but more so for V4 in absolute terms) when the length is increased beyond 9 digits. This is due to the TRUNC(BIN) requirement that input data may contain up to the full integer half/full/double word of data (and extra data type conversions and library routines are required).
The third and final experiment specified the TRUNC(OPT) compiler option. TRUNC(OPT) is a performance option. The compiler assumes that input data conforms to the PICTURE clause and then allows the compiler the freedom to manipulate data in either of the following ways that are most optimal:
  • Correcting back to the PICTURE clause as with TRUNC(STD) or
  • Only correcting back to the two, four or eight byte boundary as with TRUNC(BIN)
Start of change
Table 3. Performance differences results of four test cases when specifying TRUNC(OPT)
TRUNC(OPT) V4 versus TEST 1 V6 versus TEST 1 V6 versus V4
TEST 1: 1-8 digits 100% 100% 97%
TEST 2: 9 digits 333.3% 69.7% 20.4%
TEST 3: 10-17 digits 209.7% 70.4% 32.7%
TEST 4: 18 digits 5553.4% 129.7% 2.3%
End of change
These results demonstrate that:
  • V6 also outperforms V4 when using TRUNC(OPT).
  • V6 shows no slow down until the 18 digit case but still vastly outperforms V4 at this longest length.
Start of changeThe performance results are compared when using TRUNC(OPT), TRUNC(STD), and TRUNC(BIN) for V6 :
Start of change
Table 4. Performance differences results when specifying TRUNC(OPT), TRUNC(STD), and TRUNC(BIN) for V6
V6 TRUNC(STD) vs TRUNC(OPT) TRUNC(BIN) vs TRUNC(OPT)
TEST 1: 1-8 digits 109.1% 94.1%
TEST 2: 9 digits 172.4% 99.7%
TEST 3: 10-17 digits 178.5% 3864.7%
TEST 4: 18 digits 105.5% 2116.1%
End of change
End of change
Note: Use the TRUNC(OPT) only if you are sure the data being moved in the binary areas conforms to the PICTURE clause otherwise unpredictable results could occur. See TRUNC in the Enterprise COBOL for z/OS® Programming Guide for more information.
Across all the TRUNC options and data item lengths just presented V6 outperforms V4. These improvements are due to the following reasons:
  • The use of 64-bit ‘G’ form instructions enables much more efficient code for > 8 digit cases
  • More efficient library routines for the very large TRUNC(BIN) cases

Prioritizing your application for migration to V6 has a specific example of binary double word arithmetic (Large Binary Arithmetic) that demonstrates the performance improvement for this type of operation relative to version 4 of the compiler. In this example V6 is considerably faster than V4 and earlier compiler releases.

The relative performance differences across the different TRUNC options have been smoothed out compared to V4. This is primarily due to the compiler inserting a runtime test for overflow. If no overflow is possible then an expensive ‘divide’ hardware instruction is avoided.

If your data is known to conform to the PICTURE clause then TRUNC(OPT) remains the best overall option to choose but relatively speaking it improves less over TRUNC(STD) than in V4 and overall absolute performance is better with either option in V6.

Although TRUNC(BIN) enables more efficient code when storing out a COMPUTE or MOVE result it continues to significantly harm the performance when these data items are used as input to arithmetic statements (as the compiler must assume the max 2,4,8 byte size). V6 optimizes the correction code for TRUNC(STD) so the performance benefit of TRUNC(BIN) has been reduced slightly.

It might be better to only specify COMP-5 for select data items versus using TRUNC(BIN). For example, performance will usually be improved if data items in COMPUTE statements in particular are not specified with COMP-5.