You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by co...@apache.org on 2026/03/23 23:24:00 UTC
(tinkerpop) 01/01: Optimize no-GValue fast path in P.setValue()
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 <Co...@improving.com>
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
/**