Replacing a Python UDF with native functions
A Python UDF serializes every row to a Python worker and blinds Catalyst; the same logic in native functions stays optimizable and runs 10 to 100x faster.
Prerequisites
PySpark 3.x
Python
from pyspark.sql import functions as F
# AVANT : UDF ligne à ligne, opaque pour l'optimiseur
# @udf("string")
# def clean_phone(p):
# return re.sub(r"[^0-9+]", "", p or "")[:15]
# APRÈS : équivalent 100 % natif, vectorisé côté JVM
df_clean = df.withColumn(
"phone_clean",
F.substring(
F.regexp_replace(F.coalesce("phone", F.lit("")), "[^0-9+]", ""),
1, 15,
),
)
# Check-list avant d'écrire une UDF : regexp_*, split, transform,
# aggregate, sequence, date_*, conv... couvrent l'immense majorité des cas.Result
+--------------------+------------+ | phone| phone_clean| +--------------------+------------+ |+33 (0)6 12 34 56 78|+33612345678| | 06-98-76-54-32| 0698765432| | null| | +--------------------+------------+ Sur 1.2 Md de lignes : UDF Python 312 s -> natif 9 s (x34)
PySparkUDFCatalystPerformance