Skip to content

Scope comparison

rand-engine, Faker, and dbldatagen overlap in synthetic-data work while using different execution and deployment models. The table records only capabilities described by the linked primary sources; it is not a ranking.

Tool Execution and output Required input or optional source Repeatability and relationships Deployment
rand-engine A declarative RandSpec runs through Python/NumPy/pandas DataGenerator, or a caller-supplied Spark session; it returns pandas frames, record streams, files, or Spark DataFrames. A RandSpec is required; generation does not read a database. A seed reconstructs stateless PK/FK values from definitions and row indexes. In Spark, an explicit seed controls keys only; ordinary Spark values remain unseeded. Python with NumPy and pandas; Spark is optional. Project source
Faker Calls a Python provider generator and can print repeated provider output through its CLI. Typical examples create Faker(); dynamic providers can supply external elements. seed and seed_instance repeat provider calls when methods and Faker version match. This page makes no multi-table relationship comparison for Faker. Python package and CLI. Faker documentation
dbldatagen A code-defined specification builds a Spark SQL DataFrame and can use the Structured Streaming Rate source. Ad-hoc specifications can run without an input dataset; its experimental analyzer can use a schema or source DataFrame. Its documentation covers repeatable multi-table, CDC, merge and join scenarios with PK/FK consistency. PySpark-compatible Spark/Databricks workflows, including notebooks and Delta Live Tables. README ยท API reference

Use Faker for provider-oriented values, dbldatagen for its Spark/Databricks-oriented generation workflows, and rand-engine where its RandSpec, stateless relations, pandas outputs, or optional Spark facade fit the application. These descriptions identify overlap, not equivalent feature sets.

rand-engine regression evidence

The recorded results and same-runner methodology measure rand-engine base and head revisions under one runner. These are rand-engine regression measurements, not a Faker or dbldatagen speed comparison.

Bounded CI observations

The following observations come from one successful, validated GitHub Actions run at harness commit bff8526cc6a5d76cb2cb8a454b69971cbf0876a5. Its retained artifact contains the machine-readable record and derived summary. The artifact was 74,765 bytes, had SHA-256 6cd6cd39239839fc38b8d021c9bc19ea33b451d5f5db21f820ba55c0c3e90a0f, and is scheduled to expire on 2027-01-16T18:14:24Z; the raw values are retained here so the observations do not depend on artifact access.

This was one GitHub-hosted Ubuntu/Linux x64 run (GitHub Actions 1000038864) on Python 3.12.15, Java (version components: 17, 0, 20, 1), and Spark 3.5.8 in local[8]. It installed the public, non-editable rand-engine 0.8.0 wheel (SHA-256 db4422a43a20605babb369ac223d526e5607f6539f5056c5d277ead22ad173ba) in an isolated environment. The direct comparison pins were Faker 28.4.1, dbldatagen 0.4.0.post1, PySpark 3.5.8, NumPy 2.1.1, pandas 2.2.3, PyArrow 23.0.1, setuptools 83.0.0, jmespath 1.0.1, and pyparsing 3.2.5.

Each side had one warm-up, then three timed samples in AB/BA/AB order. Setup, warm-up, and output validation were outside the timed generation samples. For the Python workload, DataGenerator and Faker were seeded with 42. For Spark, rand-engine's seed 42 controls its key generation only; dbldatagen used randomSeed=42 and hash_fieldname. The Spark payload values are not claimed to repeat exactly across the two implementations.

The shared Python contract was exactly 100,000 dictionaries with value: int in 0..999999, tier: str in bronze, silver, or gold, and active: bool. The timed rand-engine call was DataGenerator(...).get_df().to_dict("records") followed by scalar normalization; Faker used direct providers for the same fields. Validation of all 100,000 outputs was outside the clock. stream_dict was not used.

The Spark contract built and fully evaluated 1,000,000 rows at eight partitions. Each timed call built its frame, selected xxhash64(ordinal, value, tier), then aggregated count(*) and the hash sum with collect(). Both observed schemas were ordinal: bigint (not nullable), value: int (nullable), and tier: string (nullable); the observed null counts were zero. Validation also recorded ordinal range 0..999999, one million distinct ordinals, and the common value and tier domains. The recorded physical plans show the hash consumes all three payload columns, rather than only counting rows.

The immutable runner, pinned requirements, and workflow at that harness commit provide the exact invocation. The workflow installs the public wheel in an isolated environment and runs the harness from outside the checkout with that environment's interpreter.

Workload Contract and validation Timed samples in seconds Median in seconds
Python: rand-engine 100,000 materialized dictionaries with value, tier, and active; validation passed 0.16667477599999359, 0.15877993899999865, 0.15641291299999693 0.15877993899999865
Python: Faker 100,000 materialized dictionaries with value, tier, and active; validation passed 0.7647746930000068, 0.7687502190000117, 0.7753420730000045 0.7687502190000117
Spark: rand-engine 1,000,000 fully evaluated rows with ordinal, value, and tier at eight partitions; validation passed 1.831968039000003, 1.340617297999998, 1.2995347960000032 1.340617297999998
Spark: dbldatagen 1,000,000 fully evaluated rows with ordinal, value, and tier at eight partitions; validation passed 0.9171129059999998, 0.3948988709999952, 0.5162802759999892 0.5162802759999892
Separate observed cost Seconds
Workflow environment creation 3.162337567
Isolated harness installation 32.132155979
Workflow bounded-observation step 59.837671308
Whole Actions job 103
Python workload setup / validation 0.38064580299999307 / 0.3279378719999926
Spark workload setup / validation 3.1340523949999977 / 32.52120048800002

These observations apply only to these two contracts, pins, runner, and three-repetition run. They are not production-throughput measurements or claims of universal speed, adoption, causal architecture, or statistical ranking. No winner is inferred.