aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Baird <baird@adacore.com>2022-07-26 17:17:17 -0700
committerMarc Poulhiès <poulhies@adacore.com>2022-09-05 09:21:06 +0200
commitcb6ff9e4198c6cd5abd915e271ea33d50f48b3d8 (patch)
tree04ab8aeaeb3d457f77b98ed7bc8cf065f4a4cbad
parent66d4ff2658fc2d5115092da29249191feac75308 (diff)
downloadgcc-cb6ff9e4198c6cd5abd915e271ea33d50f48b3d8.zip
gcc-cb6ff9e4198c6cd5abd915e271ea33d50f48b3d8.tar.gz
gcc-cb6ff9e4198c6cd5abd915e271ea33d50f48b3d8.tar.bz2
[Ada] Single-element Append performance improvement
Ada.Containers.Vectors has two Append procedures that take an Element value; one takes a Count parameter and one does not (the count is implicitly one for the latter). For the former version, there was code that took a faster path if certain conditions were met and otherwise took a slower path; one of the prerequisite conditions for this was Count = 1. For the latter version, no such special-case detection was performed; the more general code was always executed. Move the special-case detection/handling code from the former version into the latter and change the former version to simply call the latter version if Count = 1. Also apply same change to Ada.Containers.Indefinite_Vectors. gcc/ada/ * libgnat/a-coinve.adb, libgnat/a-convec.adb (Append): If the Append that takes an Element and a Count is called with Count = 1, then call the Append that does not take a Count parameter; otherwise call the code that handles the general case. Move the special case detection/handling code that was formerly in that version of Append into the version that does not take a Count parameter, so that now both versions get the performance benefit.
-rw-r--r--gcc/ada/libgnat/a-coinve.adb41
-rw-r--r--gcc/ada/libgnat/a-convec.adb47
2 files changed, 49 insertions, 39 deletions
diff --git a/gcc/ada/libgnat/a-coinve.adb b/gcc/ada/libgnat/a-coinve.adb
index c84175a..46d6730 100644
--- a/gcc/ada/libgnat/a-coinve.adb
+++ b/gcc/ada/libgnat/a-coinve.adb
@@ -197,12 +197,29 @@ is
Count : Count_Type)
is
begin
- -- In the general case, we pass the buck to Insert, but for efficiency,
- -- we check for the usual case where Count = 1 and the vector has enough
- -- room for at least one more element.
+ -- In the general case, we take the slow path; for efficiency,
+ -- we check for the common case where Count = 1 .
- if Count = 1
- and then Container.Elements /= null
+ if Count = 1 then
+ Append (Container, New_Item);
+ else
+ Append_Slow_Path (Container, New_Item, Count);
+ end if;
+ end Append;
+
+ ------------
+ -- Append --
+ ------------
+
+ procedure Append (Container : in out Vector;
+ New_Item : Element_Type)
+ is
+ begin
+ -- For performance, check for the common special case where the
+ -- container already has room for at least one more element.
+ -- In the general case, pass the buck to Insert.
+
+ if Container.Elements /= null
and then Container.Last /= Container.Elements.Last
then
TC_Check (Container.TC);
@@ -223,23 +240,11 @@ is
Container.Elements.EA (New_Last) := new Element_Type'(New_Item);
Container.Last := New_Last;
end;
-
else
- Append_Slow_Path (Container, New_Item, Count);
+ Insert (Container, Last_Index (Container) + 1, New_Item, 1);
end if;
end Append;
- ------------
- -- Append --
- ------------
-
- procedure Append (Container : in out Vector;
- New_Item : Element_Type)
- is
- begin
- Insert (Container, Last_Index (Container) + 1, New_Item, 1);
- end Append;
-
----------------------
-- Append_Slow_Path --
----------------------
diff --git a/gcc/ada/libgnat/a-convec.adb b/gcc/ada/libgnat/a-convec.adb
index 3a2adae..751d468 100644
--- a/gcc/ada/libgnat/a-convec.adb
+++ b/gcc/ada/libgnat/a-convec.adb
@@ -173,27 +173,11 @@ is
Count : Count_Type)
is
begin
- -- In the general case, we pass the buck to Insert, but for efficiency,
- -- we check for the usual case where Count = 1 and the vector has enough
- -- room for at least one more element.
-
- if Count = 1
- and then Container.Elements /= null
- and then Container.Last /= Container.Elements.Last
- then
- TC_Check (Container.TC);
-
- -- Increment Container.Last after assigning the New_Item, so we
- -- leave the Container unmodified in case Finalize/Adjust raises
- -- an exception.
-
- declare
- New_Last : constant Index_Type := Container.Last + 1;
- begin
- Container.Elements.EA (New_Last) := New_Item;
- Container.Last := New_Last;
- end;
+ -- In the general case, we take the slow path; for efficiency,
+ -- we check for the common case where Count = 1 .
+ if Count = 1 then
+ Append (Container, New_Item);
else
Append_Slow_Path (Container, New_Item, Count);
end if;
@@ -222,7 +206,28 @@ is
New_Item : Element_Type)
is
begin
- Insert (Container, Last_Index (Container) + 1, New_Item, 1);
+ -- For performance, check for the common special case where the
+ -- container already has room for at least one more element.
+ -- In the general case, pass the buck to Insert.
+
+ if Container.Elements /= null
+ and then Container.Last /= Container.Elements.Last
+ then
+ TC_Check (Container.TC);
+
+ -- Increment Container.Last after assigning the New_Item, so we
+ -- leave the Container unmodified in case Finalize/Adjust raises
+ -- an exception.
+
+ declare
+ New_Last : constant Index_Type := Container.Last + 1;
+ begin
+ Container.Elements.EA (New_Last) := New_Item;
+ Container.Last := New_Last;
+ end;
+ else
+ Insert (Container, Last_Index (Container) + 1, New_Item, 1);
+ end if;
end Append;
----------------------