About

ib_alps_selfyAbout me

I, Igor Babic, am a programmer for life, living in Slovenia.

Writing articles is hard, but I do it anyway because I always forget small things and then search all over the internet for advise.

 

2 Replies to “About”

  1. Hello Igor,

    I was looking at your language comparisons, in particular the Ada version, and I think one reason why the Ada version is slower is because there are two subprogram calls whereas the other language examples only use a single call, and subprogram calls are expensive. Also, I would not use the unbounded_string package for this example, which has to deal with memory allocation and deallocation. Rather I use just use a discriminated type. Also, I thought it would be good to show an example of how an Ada programmer might be more likely to write the program, which I did. In so doing, I believe my Ada version caught and reported and error that could be called a bug that is present in all the program examples. That is, it appears the intention is to print out the final value of the loops, but the 50_000_000 value actually comes from the second last loop iteration. The final iteration produces the result 50_000_001. This is not something I noticed, but something that was reported as a constrait_error exception when running the program.

    I wrote the example using current Ada 2012 standard syntax, which provides an example of contracts with a type invariant and post condition, and using constrained subtypes that can only be assigned valid values. I found that the initialization of the Calculator object in the loop (to satisfy the type_invariant) doubles the execution time. So, if I wanted to double the speed I would remove the type_invariant and the initializers on the components of the calculator type. But I figure, a strength of Ada is safety and security, so it is better to have the type invariant, and be sure that all values of Calculator objects are valid, which is something the other language examples dont do.

    If you are interested, here is my version of the Ada code….

    Regards,
    Brad

    pragma Assertion_Policy (Type_Invariant => Ignore); — Can turn off checking if desired

    with Ada; use Ada;
    with Ada.Calendar;
    with Ada.Text_IO; use Ada.Text_IO;
    with Ada.Command_Line;

    with Calculators;

    procedure Main
    is
    Default_Max_Counter : constant := 50_000_000;

    Max_Counter : constant Natural :=
    (if Command_Line.Argument_Count = 1
    then Natural’Value (Command_Line.Argument (1))
    else Default_Max_Counter);

    subtype Counter is Natural range 1 .. Max_Counter;

    package Test_Calculators is new Calculators (Counter);

    Start_Time : constant Calendar.Time := Calendar.Clock;
    use type Calendar.Time;

    Result : Test_Calculators.Result_Value;

    begin — Main

    for I in Counter loop
    declare
    C : Test_Calculators.Calculator;
    begin
    Result := C.Calculate (Count => I);
    end;
    end loop;

    Put_Line (“Time: ” & Duration’Image (Calendar.Clock – Start_Time) & ” s”);
    end Main;
    generic
    type Counter is range ;
    package Calculators is

    subtype Result_Value is Counter’Base range
    Counter’First + 1 .. Counter’Last + 1;

    type Calculator is tagged private;

    function Calculate (New_Calculator : out Calculator;
    Count : Counter) return Result_Value
    with Post => Calculate’Result = Count + 1;

    private

    Name_Prefix : constant String := “Name”;

    Min_Name_Length : constant Positive :=
    Name_Prefix’Length + Result_Value’Image (Result_Value’First)’Length;

    Max_Name_Length : constant Positive :=
    Name_Prefix’Length + Result_Value’Image (Counter’Last)’Length;

    subtype Name_Lengths is Positive range Min_Name_Length .. Max_Name_Length;

    type Name_String (Name_Length : Name_Lengths := Name_Lengths’Last) is
    record
    Value : String (1 .. Name_Length);
    end record;

    type Calculator is tagged
    record
    Result : Result_Value := Result_Value’Last;
    Name : Name_String :=
    (Name_Length => Max_Name_Length,
    Value =>
    Name_Prefix & Result_Value’Image (Result_Value’Last));
    end record
    with Type_Invariant =>
    Name.Value (1 .. Name_Prefix’Length) = Name_Prefix
    and then
    Result_Value’Value
    (Name.Value (Name_Prefix’Length + 1 .. Name.Value’Last)) = Result;

    end Calculators;

    with Ada.Text_IO; use Ada.Text_IO;

    package body Calculators is

    function Calculate (New_Calculator : out Calculator;
    Count : Counter) return Result_Value
    is
    Result : constant Result_Value := Count + 1;
    Name : constant String := Name_Prefix & Result_Value’Image (Result);
    begin
    New_Calculator :=
    (Result => Result,
    Name => (Name_Length => Name’Length,
    Value => Name));

    if Result = Result_Value’Last then
    Put_Line (New_Calculator.Name.Value);
    end if;

    return Result;

    end Calculate;

    end Calculators;

Leave a Reply

Your email address will not be published.