Speed or Readability…

I have been thinking about an issue of speed versus readability lately. Which one prevails over the other. I have a case statement and a loop which positions can be interchanged to come to the same result.

Consider these two implementations:

DECLARE caseexpr PLS_INTEGER; var NUMBER; starttime pls_integer; endtime pls_integer; BEGIN caseexpr := 1; var := 0; FOR idx IN 1 .. 10000000 LOOP CASE caseexpr WHEN 1 THEN var := var + 1; WHEN 2 THEN var := var + 2; WHEN 3 THEN var := var + 3; WHEN 4 THEN var := var + 4; END CASE; END LOOP; DBMS_OUTPUT.PUT_LINE(to_char(var)); END; /

         

DECLARE caseexpr PLS_INTEGER; var NUMBER; BEGIN caseexpr := 1; var := 0; CASE caseexpr WHEN 1 THEN FOR idx IN 1 .. 10000000 LOOP var := var + 1; END LOOP; WHEN 2 THEN FOR idx IN 1 .. 10000000 LOOP var := var + 2; END LOOP; WHEN 3 THEN FOR idx IN 1 .. 10000000 LOOP var := var + 3; END LOOP; WHEN 4 THEN FOR idx IN 1 .. 10000000 LOOP var := var + 4; END LOOP; END CASE; DBMS_OUTPUT.PUT_LINE(to_char(var)); END;

The first on has one (1) loop in which the case expression is evaluated a lot of times. The second has one (1) case expression which holds a loop for every possible case.

When I ran and timed these snippets (using SELECT to_char(systimestamp, ‘SS:FF6’) FROM dual; before and after the snippets) on both Oracle 11G and Oracle 9i, it appeared the second one performed a little bit faster than the first one. I had to have the loop run 10000000 times to see a little difference, less than half a second, but the second one was a bit faster.

But when it comes to readability, I think the first one wins. This also goes for the maintainability. What if I want to change the loop. The first one just needs a change in one line, the second one needs changes in every case branch.

Seeing that the differences are so tiny, I think I will choose the first option as my implementation, since this is more readable and better maintainable.

2 thoughts on “Speed or Readability…

  1. I agree that sometimes it is a trade-off. Another option may be an intermediate result, such as:
    DECLARE
    caseexpr PLS_INTEGER;
    var NUMBER;
    val NUMBER;
    starttime pls_integer;
    endtime pls_integer;
    BEGIN
    caseexpr := 1;
    var := 0;
    CASE caseexpr
    WHEN 1 THEN
    val := 1;
    WHEN 2 THEN
    val := 2;
    WHEN 3 THEN
    val := 3;
    WHEN 4 THEN
    val := 4;
    END CASE;

    FOR idx IN 1 .. 10000000 LOOP
    var := var + val;
    END LOOP;
    DBMS_OUTPUT.PUT_LINE(to_char(var));
    END;
    /


  2. That’s nice solution, but every case branch needs to call a different function, which makes it a bit harder. The two scripts were made just to try out which one is faster 😉


Leave a Reply

Your email address will not be published.