Generated: 2026-07-10 13:46 UTC
Vendor commits: tgen e598767, jngen 8d1e33b

tgen vs jngen — Feature Comparison

Comparison of non-trivial generation operations. See benchmarks below.

Graphs

OperationjngentgenNotesBenchmark
Connected random graph
Yes
DocsNon‑uniform*O(n + m log n) time*
Yes
DocsNon‑uniformO(n + m log^2 n) expected time
Same Prüfer tree + rejection edge add. Neither uniform over all connected labeled graphs.
jngen
1832 ms
tgen
405 ms

0.22x
n=106, m=106
Random graph with fixed n, m
Yes
DocsNon‑uniform*O(n + m log n) time*
Yes
DocsUniformO(n + m log^2 n) expected time
Rejection sampling with constraint machinery.(m=n)
jngen
901 ms
tgen
425 ms

0.47x
n=106, m=106

(m=2n)
jngen
2287 ms
tgen
971 ms

0.42x
n=106, m=2×106
Skewed / stretched connected graph
Yes
DocsNon‑uniformO(n + m log n) time* if spread is O(1)Omega(n * m) time* otherwise
Yes
DocsNon‑uniformO(n + m log n) time if spread is O(1)O(n log n + m log^2 n) expected time otherwise
Same high-level algorithm: skewed spanning tree, then ancestor-biased extra edges. Extra edges reject duplicates; jngen resets an attempt counter on success and throws after MAX_ATTEMPTS=1000 consecutive failures, while tgen uses its unique generation framework. For large spread, tgen uses binary lifting; jngen uses trivial parent-by-parent lifting.(m=n)
jngen
1204 ms
tgen
426 ms

0.35x
n=106, m=106, elongation=100, spread=2

(distinct worst)
jngen
FAILURE
tgen
779 ms
n=106, m=2n-3, elongation=100, spread=2
Bipartite graph (random / complete)
Yes
DocsUniform*O(n1 + n2 + m log(n1 * n2)) time*
Yes
DocsUniformO(n1 + n2 + m log(n1 * n2)) expected time
tgen: Distinct edge-index sampling. jngen: Rejection sampling. Both support optional connected generation. jngen also supports allowMulti; tgen stores simple graphs only.
jngen
526 ms
tgen
102 ms

0.19x
n1=103, n2=103, m=5×105
Directed random graph
Yes
DocsNon‑uniform*O(n + m log n) time*
Yes
DocsNon‑uniformO(n + m log^2 n) expected time
tgen: Rejection with constraint machinery. jngen: Rejection sampling.(directed)
jngen
1274 ms
tgen
485 ms

0.38x
n=106, m=106

(DAG)
jngen
1488 ms
tgen
629 ms

0.42x
n=106, m=106
Directed acyclic random graph (DAG)
Yes
DocsNon‑uniform*O(n + m log n) time*
Yes
DocsNon‑uniformO(n + m log^2 n) expected time
tgen: Randomized Kahn topological order, then rejection sampling. jngen: Rejection sampling + acyclic shuffle-orient.
jngen
1488 ms
tgen
629 ms

0.42x
n=106, m=106

* Uniformity or complexity is undocumented and is inferred by code inspection.

Trees

OperationjngentgenNotesBenchmark
Random labeled tree
Yes
DocsUniformO(n) time*
Yes
DocsUniformO(n) time
Prüfer sequence.
jngen
1234 ms
tgen
900 ms

0.73x
n=106
Skewed tree (wnext / Prim-like)
Yes
DocsNon‑uniform*O(n) time*
Yes
DocsNon‑uniformO(n) time
Uses parent(i) = wnext(i, elongation).
jngen
577 ms
tgen
324 ms

0.56x
n=106, elongation=100
Random tree (Kruskal-like)
Yes
DocsNon‑uniform*O(n log(n) alpha(n)) expected time*
Yes
DocsNon‑uniformO(n log(n) alpha(n)) expected time
Kruskal-like edge add until connected.
jngen
1315 ms
tgen
941 ms

0.72x
n=106

* Uniformity or complexity is undocumented and is inferred by code inspection.

Lists and sequences

OperationjngentgenNotesBenchmark
Distinct values in range
Yes
DocsUniform*O(k log k) expected time*
tgen: Fisher–Yates + forbidden-value map. jngen: Hash-set rejection.
jngen
2806 ms
tgen
2227 ms

0.79x
n=5×106, value_left=1, value_right=10×106
Random integer list (duplicates allowed)
Yes
DocsUniform*O(k) time*
Independent uniform draws.
jngen
162 ms
tgen
132 ms

0.81x
n=5×106, value_left=1, value_right=10×106
Uniform random permutation
Yes
DocsUniform*O(n) time*
Yes
DocsUniformO(n) time
jngen
314 ms
tgen
303 ms

0.97x
n=5×106
Declarative constraints (palindrome, cycles)NoConstraint-based uniform sampling.

* Uniformity or complexity is undocumented and is inferred by code inspection.

Math

OperationjngentgenNotesBenchmark
Partition into k parts (fast)
Yes
DocsNon‑uniform*O(k log k) time*
Same high-level approach: random delimiters, sort, gap recovery. jngen also sorts parts in non-increasing order and shuffles; tgen fast omits reordering. Not uniformly random; Optimized for speed.
jngen
982 ms
tgen
506 ms

0.51x
n=1018, k=3×106, part_left=0
Uniform ordered partition into k parts (composition)No
Yes
DocsUniformO(n) time if unbounded part_rightO(n·k) time otherwise
Stars-and-bars or DP in log space. Uniform over ordered compositions.tgen: 1305 ms
n=5×107, k=10, part_left=0
Uniform ordered partition, variable number of partsNoDP in log space.tgen: 2102 ms
n=4.8×106
Random integer with congruence constraintsNo
Yes
DocsUniformO(|mods| + log r) time
Partition array into k groups
Yes
DocsUniform if unbounded max_sizeNon‑uniform otherwiseO(n) time if unbounded max_sizeO(n + k log k) time otherwise
jngen
455 ms
tgen
183 ms

0.40x
n=106, k=106

* Uniformity or complexity is undocumented and is inferred by code inspection.

Geometry

OperationjngentgenNotesBenchmark
Random convex polygon (non strict)NoValtr lattice walk; Collinear boundary vertices allowed.tgen: 2213 ms
n=106, min=0, max=3×1010, strict=false
Random convex polygon
Yes
DocsNon‑uniform*O(n log n) time*
Both sample extra vertices then subsample to n: jngen hull of 10n ellipse points; tgen Valtr walk on n + max(100, n/1000) grid lines, collinear removal, subsample.
jngen
TIMEOUT
tgen
2702 ms
n=106, min=0, max=1012, strict=true
Points in general position (no three collinear)
Yes
DocsNon‑uniform*O(n² log n) expected time*
tgen: Algebraic construction over F_p. jngen: Rejection until no collinearity.
jngen
TIMEOUT
tgen
496 ms
n=106, min=0, max=3×106
Random simple polygonNoDefault (strict=false) samples distinct grid points, then polygonizes; Strict=true uses general-position vertices (v1.0.0 behavior). Collinear triples may appear on the boundary when strict=false.tgen: 3172 ms
n=106, min=0, max=3×106, strict=false
Random orthogonal polygonNo
Yes
DocsNon‑uniformO(n²) time for n <= 1000O(n) time otherwise
Axis-aligned simple polygon grown by local boundary edits. With strict=true, every vertex is a 90-degree turn.tgen: 51 ms
n=106, min=0, max=3×106, strict=false
Simple polygon through given pointsNo
Yes
DocsNon‑uniformO(n log n) expected time
Randomized divide-and-conquer Hamiltonian path.tgen: 2303 ms
n=106

* Uniformity or complexity is undocumented and is inferred by code inspection.

Strings

OperationjngentgenNotesBenchmark
Regex / pattern strings
Yes
DocsUniformO(output length) expected time
Same testlib-style regex syntax. tgen samples uniformly among matches (documented); jngen explicitly does not: e.g. Rnd.next("[1-9][0-9]{1,2}") does not yield uniform digit strings. Benchmark measures generation throughput at fixed pattern length, not distributional fairness.
jngen
798 ms
tgen
788 ms

0.99x
pattern=(([1-9][0-9]{3}|[A-F]{4})|(ab|cd){2}){r}, len=107

* Uniformity or complexity is undocumented and is inferred by code inspection.

Hacks

OperationjngentgenNotesBenchmark
Polynomial hash collision strings (signed mod)Deterministic collision construction, not random sampling. Both generate colliding strings for rolling hash.
Polynomial hash collision (unsigned / power-of-two mod)NoThue–Morse construction.
std::unordered_set collision inputsOverlap in purpose; Different APIs and compiler support. jngen: GCC 4.x only; Tuned load factor/reserve. tgen: GCC multiplier-based collision keys.
std::set collision stringsNoDistinct strings with equal std::set ordering keys.
Max-flow worst case (Dinitz / Edmonds-Karp)NoZadeh network.
Mo's algorithm worst-case queriesNo
Yes
DocsO(n log n + q) time
SPFA TLE graphNo
Yes
DocsO(n) time
Graph with n vertices and edges; Forces Ω(n²) relaxations.
Stale-heap Dijkstra bug graphNoForces Ω(n²) without stale-heap skip.
Non-strict relaxation Dijkstra bug graphNoForces Ω(2^{n/2}) with non-strict relaxation.
MT19937 XOR-hash collision maskNoBitmask for int or long long outputs.
Segment-tree-beats worst caseNo
Rotating calipers bug polygonNoFixed 6-vertex convex polygon.

* Uniformity or complexity is undocumented and is inferred by code inspection.

Other

OperationjngentgenNotesBenchmark
Distinct generationNo
Yes
DocsUniformO(T log k + log^2 k) time amortized expected per call when generating k values and next() runs in O(T)
Composable constraint machinery.
Testlib integrationNojngen is built on testlib. tgen is a standalone header with register_gen and its own constraint API.
Built-in SVG visualizationNojngen Drawer for points, segments, circles, polygons; Outputs SVG.
Accelerated build guideNoCompile jngen.h once into a static lib; Link with JNGEN_DECLARE_ONLY for faster rebuilds.

Samples

Geometry

Operationjngentgen
Random convex polygon
Yes
DocsNon‑uniform*O(n log n) time*
n=80, min=0, max=1000
jngen sample
n=15000, min=0, max=3×109
jngen sample
n=80, min=0, max=1000
tgen sample
n=15000, min=0, max=3×109
tgen sample
Points in general position (no three collinear)
Yes
DocsNon‑uniform*O(n² log n) expected time*

n=2000, min=0, max=3×106
jngen sample

n=2000, min=0, max=3×106
tgen sample
Random simple polygonNo
n=80, min=0, max=1000
tgen sample
Random orthogonal polygonNo
n=80, min=0, max=1000
tgen sample
Simple polygon through given pointsNo
Yes
DocsNon‑uniformO(n log n) expected time

10×10 input grid, min=0, max=1000
tgen sample

* Uniformity or complexity is undocumented and is inferred by code inspection.

tgen vs jngen — Benchmarks

Timing comparison

Bar length is relative to the slower library per operation (jngen vs tgen). Ratio is colored by the faster library.

OperationParametersComparisonRatio (tgen/jngen)
graph::get_connected (m=n)Docsn=106, m=106
jngen
1832 ms
tgen
405 ms
0.22x
graph::get_connected (m=2n)Docsn=106, m=2×106
jngen
2841 ms
tgen
1073 ms
0.38x
graph::gen (m=n)Docsn=106, m=106
jngen
901 ms
tgen
425 ms
0.47x
graph::gen (m=2n)Docsn=106, m=2×106
jngen
2287 ms
tgen
971 ms
0.42x
graph::gen_skewed (m=n)Docsn=106, m=106, elongation=100, spread=2
jngen
1204 ms
tgen
426 ms
0.35x
graph::gen_skewed (m=2n)Docsn=106, m=2×106, elongation=100, spread=6
jngen
2620 ms
tgen
1072 ms
0.41x
graph::gen_skewed (distinct worst)Docsn=106, m=2n-3, elongation=100, spread=2
jngen
FAILURE
Cannot generate random stretched graph with parameters 1000000, 1999997, 100, 2 (assertion `false' failed).
tgen
779 ms
tree::genDocsn=106
jngen
1234 ms
tgen
900 ms
0.73x
tree::gen_skewedDocsn=106, elongation=100
jngen
577 ms
tgen
324 ms
0.56x
tree::gen_kruskalDocsn=106
jngen
1315 ms
tgen
941 ms
0.72x
list<int>::gen (all_different)Docsn=5×106, value_left=1, value_right=10×106
jngen
2806 ms
tgen
2227 ms
0.79x
list<int>::genDocsn=5×106, value_left=1, value_right=10×106
jngen
162 ms
tgen
132 ms
0.81x
geometry::random_convex_polygon (strict)Docsn=106, min=0, max=1012, strict=true
jngen
TIMEOUT
single run exceeded 5000 ms limit
tgen
2702 ms
geometry::random_points_general_positionDocsn=106, min=0, max=3×106
jngen
TIMEOUT
single run exceeded 5000 ms limit
tgen
496 ms
permutation::genDocsn=5×106
jngen
314 ms
tgen
303 ms
0.97x
graph::gen_bipartiteDocsn1=103, n2=103, m=5×105
jngen
526 ms
tgen
102 ms
0.19x
graph::gen (directed)Docsn=106, m=106
jngen
1274 ms
tgen
485 ms
0.38x
graph::get_acyclic (DAG)Docsn=106, m=106
jngen
1488 ms
tgen
629 ms
0.42x
str::genDocspattern=(([1-9][0-9]{3}|[A-F]{4})|(ab|cd){2}){r}, len=107
jngen
798 ms
tgen
788 ms
0.99x
math::gen_partition_fixed_size_fastDocsn=1018, k=3×106, part_left=0
jngen
982 ms
tgen
506 ms
0.51x
math::partition_elementsDocsn=106, k=106
jngen
455 ms
tgen
183 ms
0.40x

tgen-only timings

OperationParameterstgen
geometry::random_convex_polygon (non strict)Docsn=106, min=0, max=3×1010, strict=false2213 ms
geometry::random_simple_polygonDocsn=106, min=0, max=3×106, strict=false3172 ms
geometry::random_orthogonal_polygonDocsn=106, min=0, max=3×106, strict=false51 ms
geometry::random_simple_polygon_through_pointsDocsn=1062303 ms
math::gen_partitionDocsn=4.8×1062102 ms
math::gen_partition_fixed_sizeDocsn=5×107, k=10, part_left=01305 ms