import%20marimo%0A%0A__generated_with%20%3D%20%220.24.0%22%0Aapp%20%3D%20marimo.App()%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20time%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20pandas%20as%20pd%0A%20%20%20%20import%20plotly.graph_objects%20as%20go%0A%20%20%20%20from%20plotly.subplots%20import%20make_subplots%0A%20%20%20%20import%20polars%20as%20pl%0A%0A%20%20%20%20%23%20Check%20for%20optional%20GPU%20libraries%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20import%20cudf%0A%0A%20%20%20%20%20%20%20%20HAS_CUDF%20%3D%20True%0A%20%20%20%20except%20ImportError%3A%0A%20%20%20%20%20%20%20%20cudf%20%3D%20None%0A%20%20%20%20%20%20%20%20HAS_CUDF%20%3D%20False%0A%20%20%20%20return%20HAS_CUDF%2C%20go%2C%20mo%2C%20np%2C%20pd%2C%20pl%2C%20time%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(go%2C%20mo)%3A%0A%20%20%20%20%23%20Visualize%20Hardware%20Memory%20Bandwidth%20Comparison%0A%20%20%20%20_devices%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%22PCIe%204.0%20x16%22%2C%0A%20%20%20%20%20%20%20%20%22Host%20CPU%20DDR5%22%2C%0A%20%20%20%20%20%20%20%20%22PCIe%205.0%20x16%22%2C%0A%20%20%20%20%20%20%20%20%22NVIDIA%20RTX%204090%20(GDDR6X)%22%2C%0A%20%20%20%20%20%20%20%20%22NVIDIA%20A100%20(HBM2e)%22%2C%0A%20%20%20%20%20%20%20%20%22NVIDIA%20H100%20(HBM3)%22%2C%0A%20%20%20%20%5D%0A%20%20%20%20_bandwidths%20%3D%20%5B31.5%2C%2084.0%2C%2063.0%2C%201008.0%2C%202039.0%2C%203350.0%5D%0A%20%20%20%20_colors%20%3D%20%5B%22%2394a3b8%22%2C%20%22%233b82f6%22%2C%20%22%2394a3b8%22%2C%20%22%2310b981%22%2C%20%22%23059669%22%2C%20%22%23047857%22%5D%0A%0A%20%20%20%20_fig%20%3D%20go.Figure(%0A%20%20%20%20%20%20%20%20go.Bar(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_bandwidths%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_devices%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20orientation%3D%22h%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker%3Ddict(color%3D_colors)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3D%5Bf%22%7Bbw%3A.1f%7D%20GB%2Fs%22%20for%20bw%20in%20_bandwidths%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20textposition%3D%22outside%22%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20)%0A%0A%20%20%20%20_fig.update_layout(%0A%20%20%20%20%20%20%20%20title%3D%22Hardware%20Memory%20Bandwidth%20Comparison%20(Roofline%20Ceiling%20for%20DataFrames)%22%2C%0A%20%20%20%20%20%20%20%20xaxis_title%3D%22Peak%20Memory%20Bandwidth%20(GB%2Fs)%20-%20Log%20Scale%22%2C%0A%20%20%20%20%20%20%20%20xaxis_type%3D%22log%22%2C%0A%20%20%20%20%20%20%20%20yaxis_title%3D%22Architecture%22%2C%0A%20%20%20%20%20%20%20%20template%3D%22plotly_white%22%2C%0A%20%20%20%20%20%20%20%20height%3D380%2C%0A%20%20%20%20%20%20%20%20margin%3Ddict(l%3D180%2C%20r%3D60%2C%20t%3D60%2C%20b%3D60)%2C%0A%20%20%20%20)%0A%0A%20%20%20%20_md%20%3D%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Hardware%20Memory%20Bandwidth%20Comparison%0A%0A%20%20%20%20Notice%20that%20PCIe%20bandwidth%20is%20lower%20than%20Host%20DDR5%20memory%20bandwidth.%20This%20creates%20a%20critical%20tradeoff%20governed%20by%20**Amdahl's%20Law**.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(np%2C%20pd%2C%20pl%2C%20time)%3A%0A%20%20%20%20%23%20Benchmark%3A%20Pandas%20(Single-threaded)%20vs%20Polars%20(Multi-threaded%20Columnar%20Rust)%0A%20%20%20%20%23%20Scale%3A%20N%20%3D%20500%2C000%20synthetic%20records%0A%20%20%20%20n_records%20%3D%20500000%0A%20%20%20%20rng%20%3D%20np.random.default_rng(42)%0A%0A%20%20%20%20ages%20%3D%20rng.integers(18%2C%2080%2C%20size%3Dn_records)%0A%20%20%20%20bmis%20%3D%20rng.normal(27.0%2C%205.0%2C%20size%3Dn_records)%0A%20%20%20%20bps%20%3D%20rng.normal(120.0%2C%2015.0%2C%20size%3Dn_records)%0A%0A%20%20%20%20%23%201.%20Pandas%20DataFrame%0A%20%20%20%20df_pd%20%3D%20pd.DataFrame(%7B%22age%22%3A%20ages%2C%20%22bmi%22%3A%20bmis%2C%20%22bp%22%3A%20bps%7D)%0A%0A%20%20%20%20t0%20%3D%20time.perf_counter()%0A%20%20%20%20res_pd%20%3D%20df_pd.groupby(%22age%22).agg(%7B%22bmi%22%3A%20%22mean%22%2C%20%22bp%22%3A%20%22max%22%7D).sort_values(by%3D%22bmi%22)%0A%20%20%20%20t_pandas%20%3D%20(time.perf_counter()%20-%20t0)%20*%201000.0%0A%0A%20%20%20%20%23%202.%20Polars%20DataFrame%20(Multi-threaded%20columnar%20execution)%0A%20%20%20%20df_pl%20%3D%20pl.DataFrame(%7B%22age%22%3A%20ages%2C%20%22bmi%22%3A%20bmis%2C%20%22bp%22%3A%20bps%7D)%0A%0A%20%20%20%20t0%20%3D%20time.perf_counter()%0A%20%20%20%20res_pl%20%3D%20(%0A%20%20%20%20%20%20%20%20df_pl.group_by(%22age%22)%0A%20%20%20%20%20%20%20%20.agg(%5Bpl.col(%22bmi%22).mean()%2C%20pl.col(%22bp%22).max()%5D)%0A%20%20%20%20%20%20%20%20.sort(%22bmi%22)%0A%20%20%20%20)%0A%20%20%20%20t_polars%20%3D%20(time.perf_counter()%20-%20t0)%20*%201000.0%0A%0A%20%20%20%20speedup_polars%20%3D%20t_pandas%20%2F%20t_polars%20if%20t_polars%20%3E%200%20else%201.0%0A%20%20%20%20return%20n_records%2C%20speedup_polars%2C%20t_pandas%2C%20t_polars%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(go%2C%20mo%2C%20n_records%2C%20speedup_polars%2C%20t_pandas%2C%20t_polars)%3A%0A%20%20%20%20_fig%20%3D%20go.Figure()%0A%0A%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20go.Bar(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D%5B%22Pandas%20(Single-Threaded)%22%2C%20%22Polars%20(Multi-Threaded%20Rust)%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D%5Bt_pandas%2C%20t_polars%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker_color%3D%5B%22%23ef4444%22%2C%20%22%233b82f6%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3D%5Bf%22%7Bt_pandas%3A.1f%7D%20ms%22%2C%20f%22%7Bt_polars%3A.1f%7D%20ms%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20textposition%3D%22outside%22%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20)%0A%0A%20%20%20%20_fig.update_layout(%0A%20%20%20%20%20%20%20%20title%3Df%22Execution%20Latency%3A%20Groupby%20Aggregation%20%26%20Sort%20(N%20%3D%20%7Bn_records%3A%2C%7D%20rows)%22%2C%0A%20%20%20%20%20%20%20%20xaxis_title%3D%22Dataframe%20Engine%22%2C%0A%20%20%20%20%20%20%20%20yaxis_title%3D%22Execution%20Time%20(ms)%22%2C%0A%20%20%20%20%20%20%20%20template%3D%22plotly_white%22%2C%0A%20%20%20%20%20%20%20%20height%3D380%2C%0A%20%20%20%20%20%20%20%20margin%3Ddict(l%3D60%2C%20r%3D40%2C%20t%3D60%2C%20b%3D60)%2C%0A%20%20%20%20)%0A%0A%20%20%20%20_md%20%3D%20mo.md(f%22%22%22%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%20Live%20Benchmark%3A%20Pandas%20vs%20Polars%0A%0A%20%20%20%20Tested%20on%20**%7Bn_records%3A%2C%7D%20rows**%3A%0A%20%20%20%20-%20**Pandas**%3A%20**%7Bt_pandas%3A.1f%7D%20ms**%0A%20%20%20%20-%20**Polars**%3A%20**%7Bt_polars%3A.1f%7D%20ms**%20(Speedup%3A%20**%7Bspeedup_polars%3A.1f%7Dx**)%0A%0A%20%20%20%20Even%20on%20CPU%2C%20columnar%20formats%20(Apache%20Arrow)%20combined%20with%20vectorized%20multi-core%20query%20execution%20in%20Polars%20eliminate%20Python%20interpreter%20overhead%20and%20maximize%20memory%20bus%20utilization.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(HAS_CUDF)%3A%0A%20%20%20%20_cudf_status%20%3D%20(%0A%20%20%20%20%20%20%20%20%22**cuDF%20is%20available**%20in%20this%20runtime.%20You%20can%20run%20%60cudf.DataFrame.from_pandas(df)%60.%22%0A%20%20%20%20%20%20%20%20if%20HAS_CUDF%0A%20%20%20%20%20%20%20%20else%20%22**cuDF%20is%20not%20installed%20%2F%20NVIDIA%20GPU%20not%20detected**%20in%20this%20environment.%20cuDF%20requires%20an%20NVIDIA%20GPU%20with%20CUDA%20drivers.%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(go%2C%20mo%2C%20np)%3A%0A%20%20%20%20%23%20Simulated%20scaling%20curves%3A%20Pandas%20vs%20Polars%20vs%20cuDF%20(GPU)%0A%20%20%20%20_sizes%20%3D%20np.array(%5B10_000%2C%2050_000%2C%20200_000%2C%201_000_000%2C%205_000_000%2C%2020_000_000%5D)%0A%0A%20%20%20%20%23%20Estimated%20latencies%20(ms)%20based%20on%20empirical%20benchmarks%20and%20memory%20bandwidth%20modeling%0A%20%20%20%20_lat_pandas%20%3D%20_sizes%20*%200.00018%20%2B%205.0%0A%20%20%20%20_lat_polars%20%3D%20_sizes%20*%200.000025%20%2B%202.0%0A%20%20%20%20%23%20cuDF%20has%20~15ms%20base%20PCIe%20transfer%20and%20launch%20latency%2C%20but%20scales%20with%20slope%201%2F20th%20of%20Polars%0A%20%20%20%20_lat_cudf%20%3D%20_sizes%20*%200.0000015%20%2B%2012.0%0A%0A%20%20%20%20_fig%20%3D%20go.Figure()%0A%0A%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20go.Scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_sizes%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_lat_pandas%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22lines%2Bmarkers%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Pandas%20(CPU%20Single-Thread)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20line%3Ddict(color%3D%22%23ef4444%22%2C%20width%3D2.5)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker%3Ddict(size%3D7)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20hovertemplate%3D%22Rows%3A%20%25%7Bx%3A%2C%7D%3Cbr%3ELatency%3A%20%25%7By%3A.1f%7D%20ms%3Cextra%3E%3C%2Fextra%3E%22%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20)%0A%0A%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20go.Scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_sizes%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_lat_polars%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22lines%2Bmarkers%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Polars%20(CPU%20Multi-Thread)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20line%3Ddict(color%3D%22%233b82f6%22%2C%20width%3D2.5)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker%3Ddict(size%3D7)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20hovertemplate%3D%22Rows%3A%20%25%7Bx%3A%2C%7D%3Cbr%3ELatency%3A%20%25%7By%3A.1f%7D%20ms%3Cextra%3E%3C%2Fextra%3E%22%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20)%0A%0A%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20go.Scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_sizes%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_lat_cudf%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22lines%2Bmarkers%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22cuDF%20(GPU%20Accelerated)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20line%3Ddict(color%3D%22%2310b981%22%2C%20width%3D2.5%2C%20dash%3D%22solid%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker%3Ddict(size%3D7)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20hovertemplate%3D%22Rows%3A%20%25%7Bx%3A%2C%7D%3Cbr%3ELatency%3A%20%25%7By%3A.1f%7D%20ms%3Cextra%3E%3C%2Fextra%3E%22%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20)%0A%0A%20%20%20%20_fig.update_layout(%0A%20%20%20%20%20%20%20%20title%3D%22Throughput%20Scaling%3A%20End-to-End%20Latency%20vs%20Row%20Count%22%2C%0A%20%20%20%20%20%20%20%20xaxis_title%3D%22Number%20of%20Rows%22%2C%0A%20%20%20%20%20%20%20%20yaxis_title%3D%22Latency%20(ms)%20-%20Log%20Scale%22%2C%0A%20%20%20%20%20%20%20%20xaxis_type%3D%22log%22%2C%0A%20%20%20%20%20%20%20%20yaxis_type%3D%22log%22%2C%0A%20%20%20%20%20%20%20%20template%3D%22plotly_white%22%2C%0A%20%20%20%20%20%20%20%20height%3D420%2C%0A%20%20%20%20%20%20%20%20margin%3Ddict(l%3D60%2C%20r%3D40%2C%20t%3D60%2C%20b%3D60)%2C%0A%20%20%20%20%20%20%20%20legend%3Ddict(x%3D0.02%2C%20y%3D0.98%2C%20bgcolor%3D%22rgba(255%2C255%2C255%2C0.8)%22)%2C%0A%20%20%20%20)%0A%0A%20%20%20%20_md%20%3D%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Scaling%20Regimes%20Across%20DataFrame%20Architectures%0A%0A%20%20%20%201.%20**Small%20Datasets%20(%24N%20%3C%2010%5E5%24%20rows)**%3A%20CPU%20Polars%20or%20Pandas%20is%20fastest.%20GPU%20kernel%20launch%20overhead%20and%20PCIe%20bus%20transfers%20dominate.%0A%20%20%20%202.%20**Medium%20Datasets%20(%2410%5E5%20%3C%20N%20%3C%2010%5E7%24%20rows)**%3A%20Polars%20provides%20outstanding%20multi-threaded%20CPU%20performance%20without%20requiring%20specialized%20GPU%20hardware.%0A%20%20%20%203.%20**Large%20Datasets%20(%24N%20%3E%2010%5E7%24%20rows)**%3A%20cuDF%20and%20GPU%20acceleration%20dominate%2C%20delivering%20order-of-magnitude%20faster%20queries%20by%20fully%20saturating%20terabyte-per-second%20memory%20buses.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
3439c5c1b2fd492f7ba6ef2eadbe969c