This is an automated email from the ASF dual-hosted git repository. colegreer pushed a commit to branch optimizePSetValue in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit a40dad0224b2d2294c083e20d996e1f00f018f9c Author: Cole Greer <[email protected]> AuthorDate: Mon Mar 23 09:56:02 2026 -0700 Optimize no-GValue fast path in P.setValue() --- CHANGELOG.asciidoc | 1 + .../tinkerpop/gremlin/process/traversal/P.java | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 36367c5255..408c3185a8 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -59,6 +59,7 @@ This release also includes changes from <<release-3-7-5, 3.7.5>>. * Added `DateTime` ontop of the existing 'datetime' grammar. * Added `UUID()` and `UUID(value)` to grammar. * Deprecated the `UnifiedChannelizer`. +* Improve performance of `P.setValue()` for large collections with no `GValue`. * Fixed bug that caused incorrect results when `tail()` used inside `repeat()`. * Modified `TraversalStrategy` construction in Javascript where configurations are now supplied as a `Map` of options. * Fixed bug in GraphSON v2 and v3 where full round trip of `TraversalStrategy` implementations was failing. diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/P.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/P.java index ff55a180ad..ca110356b4 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/P.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/P.java @@ -127,10 +127,16 @@ public class P<V> implements Predicate<V>, Serializable, Cloneable { isCollection = false; } else if (value instanceof Collection) { isCollection = true; - if (((Collection<?>) value).stream().anyMatch(v -> v instanceof GValue)) { + final Collection<V> vCollection = (Collection<V>) value; + + // fast path: if no GValues in the collection, use collection directly + if (!containsGValue(vCollection)) { + if (value instanceof BulkSet) { + this.literals = vCollection; + } + } else { this.literals = (value instanceof BulkSet) ? new BulkSet<>() : new ArrayList<>(); - for (Object v : ((Collection<?>) value)) { - // Separate variables and literals + for (final Object v : vCollection) { if (v instanceof GValue) { if (((GValue<V>) v).isVariable()) { variables.put(((GValue<V>) v).getName(), ((GValue<V>) v).get()); @@ -141,8 +147,6 @@ public class P<V> implements Predicate<V>, Serializable, Cloneable { literals.add((V) v); } } - } else { - literals = (Collection<V>) value; // Retain original collection when possible } } else { isCollection = false; @@ -224,6 +228,13 @@ public class P<V> implements Predicate<V>, Serializable, Cloneable { return results; } + private static boolean containsGValue(final Collection<?> collection) { + for (final Object o : collection) { + if (o instanceof GValue) return true; + } + return false; + } + //////////////// statics /**
