• Optimising code

    From Robert Prins@21:1/5 to All on Thu Apr 3 11:26:34 2025
    XPost: alt.lang.asm

    Hi all,

    I'm, sort-of, looking at optimising the flow of some code. It doesn't really serve a lot of real-life purpose, but I'm just curious.

    This is the original PL/I code, where I walk through a set of items in a linked list, the outer do-loop, and a PL/I "SELECT" statement is comparable to a Pascal
    (or C, where every selection is followed by a "break") case statement.

    /*------------------------------------------------------------------+
    | Process set of data |
    +------------------------------------------------------------------*/
    do list_ptr = list_own repeat list_nxt
    while(list_ptr ^= sysnull());
    select;
    /*--------------------------------------------------------------+
    | Process countries (7,353 vvvv *S* T383R13 2025-03-26T14:30) |
    +--------------------------------------------------------------*/
    when (data_list.split ^= '#' &
    data_list.split ^= '!' &
    data_list.cnty ^= '* ')
    ...

    /*--------------------------------------------------------------+
    | Process splits (4,923 vvvv *S* T383R13 2025-03-26T14:30) |
    +--------------------------------------------------------------*/
    when (data_list.split = '!')
    ...

    /*--------------------------------------------------------------+
    | Process days (446 vvvv *S* T383R13 2025-03-26T14:30) |
    +--------------------------------------------------------------*/
    when (data_list.split = '#')
    ...

    other;
    end;
    end;

    During our basic PL/I training, almost 40 years ago, we were taught to put the most frequently occurring case as the first, but given that a PL/I "SELECT" statement can have two possible formats, i.e.

    select(myvar);
    when(value1)...
    when(value2)...
    other...
    end;

    and

    select;
    when(var = value)...
    when(other_var = other_value)...
    other...
    end;

    or, like in the real code above, multiple conditions, I wonder if the above is really optimal, as e.g. moving the second "WHEN" into the first position would allow removing the now redundant "data_list.split ^= '!'" from the now second original first, eliminating a compare instruction, with a possible mispredicted jump.

    Any opinions?

    Robert
    --
    Robert AH Prins
    robert(a)prino(d)org
    The hitchhiking grandfather - https://prino.neocities.org/
    Some REXX code for use on z/OS - https://prino.neocities.org/zOS/zOS-Tools.html

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rosario19@21:1/5 to Robert Prins on Thu Apr 3 22:28:45 2025
    XPost: alt.lang.asm

    On Thu, 3 Apr 2025 11:26:34 +0000, Robert Prins wrote:

    Hi all,

    I'm, sort-of, looking at optimising the flow of some code. It doesn't really >serve a lot of real-life purpose, but I'm just curious.

    This is the original PL/I code, where I walk through a set of items in a linked
    list, the outer do-loop, and a PL/I "SELECT" statement is comparable to a Pascal
    (or C, where every selection is followed by a "break") case statement.

    /*------------------------------------------------------------------+
    | Process set of data |
    +------------------------------------------------------------------*/
    do list_ptr = list_own repeat list_nxt
    while(list_ptr ^= sysnull());
    select;
    /*--------------------------------------------------------------+
    | Process countries (7,353 vvvv *S* T383R13 2025-03-26T14:30) |
    +--------------------------------------------------------------*/
    when (data_list.split ^= '#' &
    data_list.split ^= '!' &
    data_list.cnty ^= '* ')
    ...

    /*--------------------------------------------------------------+
    | Process splits (4,923 vvvv *S* T383R13 2025-03-26T14:30) |
    +--------------------------------------------------------------*/
    when (data_list.split = '!')
    ...

    /*--------------------------------------------------------------+
    | Process days (446 vvvv *S* T383R13 2025-03-26T14:30) |
    +--------------------------------------------------------------*/
    when (data_list.split = '#')
    ...

    I don't know the language but it seems to me if after each "when"
    there is a return, it is possible doing something as
    when (data_list.split = '!') doOperation return
    when (data_list.split = '#') doOperation return
    and the remain the code that follow
    "when (data_list.split ^= '#' &data_list.split ^=
    '!'&data_list.cnty ^= '* ')"

    other;
    end;
    end;

    During our basic PL/I training, almost 40 years ago, we were taught to put the
    most frequently occurring case as the first, but given that a PL/I "SELECT" >statement can have two possible formats, i.e.

    select(myvar);
    when(value1)...
    when(value2)...
    other...
    end;

    and

    select;
    when(var = value)...
    when(other_var = other_value)...
    other...
    end;

    or, like in the real code above, multiple conditions, I wonder if the above is
    really optimal, as e.g. moving the second "WHEN" into the first position would
    allow removing the now redundant "data_list.split ^= '!'" from the now second >original first, eliminating a compare instruction, with a possible mispredicted
    jump.

    Any opinions?

    Robert

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter Flass@21:1/5 to [email protected] on Thu Apr 3 16:09:17 2025
    XPost: alt.lang.asm

    Rosario19 <[email protected]d> wrote:
    On Thu, 3 Apr 2025 11:26:34 +0000, Robert Prins wrote:

    Hi all,

    I'm, sort-of, looking at optimising the flow of some code. It doesn't really >> serve a lot of real-life purpose, but I'm just curious.

    This is the original PL/I code, where I walk through a set of items in a linked
    list, the outer do-loop, and a PL/I "SELECT" statement is comparable to a Pascal
    (or C, where every selection is followed by a "break") case statement.

    /*------------------------------------------------------------------+
    | Process set of data |
    +------------------------------------------------------------------*/
    do list_ptr = list_own repeat list_nxt
    while(list_ptr ^= sysnull());
    select;
    /*--------------------------------------------------------------+
    | Process countries (7,353 vvvv *S* T383R13 2025-03-26T14:30) |
    +--------------------------------------------------------------*/
    when (data_list.split ^= '#' &
    data_list.split ^= '!' &
    data_list.cnty ^= '* ')
    ...

    /*--------------------------------------------------------------+
    | Process splits (4,923 vvvv *S* T383R13 2025-03-26T14:30) |
    +--------------------------------------------------------------*/
    when (data_list.split = '!')
    ...

    /*--------------------------------------------------------------+
    | Process days (446 vvvv *S* T383R13 2025-03-26T14:30) |
    +--------------------------------------------------------------*/
    when (data_list.split = '#')
    ...

    I don't know the language but it seems to me if after each "when"
    there is a return, it is possible doing something as
    when (data_list.split = '!') doOperation return
    when (data_list.split = '#') doOperation return
    and the remain the code that follow
    "when (data_list.split ^= '#' &data_list.split ^'!'&data_list.cnty ^= '* ')"

    other;
    end;
    end;

    During our basic PL/I training, almost 40 years ago, we were taught to put the
    most frequently occurring case as the first, but given that a PL/I "SELECT" >> statement can have two possible formats, i.e.

    select(myvar);
    when(value1)...
    when(value2)...
    other...
    end;

    and

    select;
    when(var = value)...
    when(other_var = other_value)...
    other...
    end;

    or, like in the real code above, multiple conditions, I wonder if the above is
    really optimal, as e.g. moving the second "WHEN" into the first position would
    allow removing the now redundant "data_list.split ^= '!'" from the now second
    original first, eliminating a compare instruction, with a possible mispredicted
    jump.

    Any opinions?

    Robert



    I’d check for ! and # in either order, and move the stuff from the first
    test to the “otherwise” (if I’m reading this right, I’m not on my computer
    to look at this).

    The problem with trying to write “optimal” code is that you never can be sure what the compiler is going to do with it, even from release to
    release.

    --
    Pete

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Prins@21:1/5 to Peter Flass on Tue Apr 8 13:59:22 2025
    XPost: alt.lang.asm

    On 2025-04-03 23:09, Peter Flass wrote:
    Rosario19 <[email protected]d> wrote:
    On Thu, 3 Apr 2025 11:26:34 +0000, Robert Prins wrote:

    Hi all,

    I'm, sort-of, looking at optimising the flow of some code. It doesn't really
    serve a lot of real-life purpose, but I'm just curious.

    This is the original PL/I code, where I walk through a set of items in a linked
    list, the outer do-loop, and a PL/I "SELECT" statement is comparable to a Pascal
    (or C, where every selection is followed by a "break") case statement.

    /*------------------------------------------------------------------+
    | Process set of data |
    +------------------------------------------------------------------*/
    do list_ptr = list_own repeat list_nxt
    while(list_ptr ^= sysnull());
    select;
    /*--------------------------------------------------------------+
    | Process countries (7,353 vvvv *S* T383R13 2025-03-26T14:30) |
    +--------------------------------------------------------------*/
    when (data_list.split ^= '#' &
    data_list.split ^= '!' &
    data_list.cnty ^= '* ')
    ...

    /*--------------------------------------------------------------+
    | Process splits (4,923 vvvv *S* T383R13 2025-03-26T14:30) |
    +--------------------------------------------------------------*/
    when (data_list.split = '!')
    ...

    /*--------------------------------------------------------------+
    | Process days (446 vvvv *S* T383R13 2025-03-26T14:30) |
    +--------------------------------------------------------------*/
    when (data_list.split = '#')
    ...

    I don't know the language but it seems to me if after each "when"
    there is a return, it is possible doing something as
    when (data_list.split = '!') doOperation return
    when (data_list.split = '#') doOperation return
    and the remain the code that follow
    "when (data_list.split ^= '#' &data_list.split ^'!'&data_list.cnty ^= '* ')"
    That's what PL/I does anyway, unlike C and some other new-fangled languages, it only executes the matching "when" clause, or if none of them matches, the "other" one (and it will actually abend if none of the "when" clauses match and there is no "other") and then jumps to the final "end" statement.

    other;
    end;
    end;

    During our basic PL/I training, almost 40 years ago, we were taught to put the
    most frequently occurring case as the first, but given that a PL/I "SELECT" >>> statement can have two possible formats, i.e.

    select(myvar);
    when(value1)...
    when(value2)...
    other...
    end;

    and

    select;
    when(var = value)...
    when(other_var = other_value)...
    other...
    end;

    or, like in the real code above, multiple conditions, I wonder if the above is
    really optimal, as e.g. moving the second "WHEN" into the first position would
    allow removing the now redundant "data_list.split ^= '!'" from the now second
    original first, eliminating a compare instruction, with a possible mispredicted
    jump.

    I’d check for ! and # in either order, and move the stuff from the first test to the “otherwise” (if I’m reading this right, I’m not on my computer
    to look at this).

    There are actually items that need to be ignored, so I need the "other" as a catch-all ignore.

    The problem with trying to write “optimal” code is that you never can be sure what the compiler is going to do with it, even from release to
    release.

    I know, although Enterprise PL/I is pretty stable, and of course my x86 assembler code does exactly what I tell it to do.

    Robert
    --
    Robert AH Prins
    robert(a)prino(d)org
    The hitchhiking grandfather - https://prino.neocities.org/
    Some REXX code for use on z/OS - https://prino.neocities.org/zOS/zOS-Tools.html

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)