11'use client' ;
22
3+ import { useState } from 'react' ;
34import { FadeIn } from '@/components/ui/FadeIn' ;
45import { GlassCard } from '@/components/ui/GlassCard' ;
56import { Button } from '@/components/ui/Button' ;
7+ import { ParseChart } from '@/components/benchmarks/ParseChart' ;
8+ import { CompetitorChart } from '@/components/benchmarks/CompetitorChart' ;
69
710const metrics = [
811 { label : 'Sustained Ops/sec' , value : '1.38M+' } ,
@@ -26,6 +29,38 @@ const methodology = [
2629 'Results averaged over 5 consecutive runs to reduce variance' ,
2730] ;
2831
32+ function RawDataToggle ( { id, children } : { id : string ; children : React . ReactNode } ) {
33+ const [ open , setOpen ] = useState ( false ) ;
34+
35+ return (
36+ < div className = "mt-4" >
37+ < button
38+ type = "button"
39+ onClick = { ( ) => setOpen ( ( prev ) => ! prev ) }
40+ className = "text-xs text-zinc-500 hover:text-zinc-300 transition-colors flex items-center gap-1"
41+ aria-expanded = { open }
42+ aria-controls = { `raw-data-${ id } ` }
43+ >
44+ < svg
45+ className = { `w-3 h-3 transition-transform duration-200 ${ open ? 'rotate-90' : '' } ` }
46+ fill = "none"
47+ viewBox = "0 0 24 24"
48+ stroke = "currentColor"
49+ strokeWidth = { 2 }
50+ >
51+ < path strokeLinecap = "round" strokeLinejoin = "round" d = "M9 5l7 7-7 7" />
52+ </ svg >
53+ { open ? 'Hide' : 'View' } raw data
54+ </ button >
55+ { open && (
56+ < div id = { `raw-data-${ id } ` } className = "mt-3" >
57+ { children }
58+ </ div >
59+ ) }
60+ </ div >
61+ ) ;
62+ }
63+
2964function renderMethodologyItem ( item : string ) {
3065 const FLAG = '-benchmem' ;
3166 const idx = item . indexOf ( FLAG ) ;
@@ -75,110 +110,121 @@ export function BenchmarksContent() {
75110 </ div >
76111 </ section >
77112
78- { /* Benchmark Table */ }
113+ { /* Parse Benchmarks Chart + Table */ }
79114 < section className = "section-padding pb-16" >
80115 < div className = "container-width" >
81116 < FadeIn >
82117 < h2 className = "text-2xl font-bold text-white mb-4" > Parse Benchmarks</ h2 >
83- < GlassCard className = "p-0 overflow-hidden" hover = { false } >
84- < div className = "overflow-x-auto" >
85- < table className = "w-full text-sm text-left" >
86- < caption className = "sr-only" > GoSQLX Parse Benchmarks</ caption >
87- < thead >
88- < tr className = "border-b border-white/[0.06]" >
89- < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Benchmark</ th >
90- < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Query Type</ th >
91- < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Apple M4</ th >
92- < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Baseline (CI)</ th >
93- </ tr >
94- </ thead >
95- < tbody >
96- { benchmarks . map ( ( b ) => (
97- < tr
98- key = { b . name }
99- className = "border-b border-white/[0.04] hover:bg-white/[0.03] transition-colors"
100- >
101- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-white font-medium" > { b . name } </ td >
102- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400" > { b . query } </ td >
103- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-mono" > { b . m4 } </ td >
104- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400 font-mono" > { b . baseline } </ td >
105- </ tr >
106- ) ) }
107- </ tbody >
108- </ table >
109- </ div >
118+ < GlassCard className = "p-6" hover = { false } >
119+ < ParseChart />
110120 </ GlassCard >
111- < p className = "text-xs text-zinc-500 mt-2 md:hidden" > ← Swipe to see all columns →</ p >
121+
122+ < RawDataToggle id = "parse" >
123+ < GlassCard className = "p-0 overflow-hidden" hover = { false } >
124+ < div className = "overflow-x-auto" >
125+ < table className = "w-full text-sm text-left" >
126+ < caption className = "sr-only" > GoSQLX Parse Benchmarks</ caption >
127+ < thead >
128+ < tr className = "border-b border-white/[0.06]" >
129+ < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Benchmark</ th >
130+ < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Query Type</ th >
131+ < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Apple M4</ th >
132+ < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Baseline (CI)</ th >
133+ </ tr >
134+ </ thead >
135+ < tbody >
136+ { benchmarks . map ( ( b ) => (
137+ < tr
138+ key = { b . name }
139+ className = "border-b border-white/[0.04] hover:bg-white/[0.03] transition-colors"
140+ >
141+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-white font-medium" > { b . name } </ td >
142+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400" > { b . query } </ td >
143+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-mono" > { b . m4 } </ td >
144+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400 font-mono" > { b . baseline } </ td >
145+ </ tr >
146+ ) ) }
147+ </ tbody >
148+ </ table >
149+ </ div >
150+ </ GlassCard >
151+ < p className = "text-xs text-zinc-500 mt-2 md:hidden" > ← Swipe to see all columns →</ p >
152+ </ RawDataToggle >
112153 </ FadeIn >
113154 </ div >
114155 </ section >
115156
116- { /* Competitor Comparison */ }
157+ { /* Competitor Comparison Chart + Table */ }
117158 < section className = "section-padding pb-16" >
118159 < div className = "container-width" >
119160 < FadeIn >
120161 < h2 className = "text-2xl font-bold text-white mb-6" > Competitor Comparison</ h2 >
121- < GlassCard className = "p-0 overflow-hidden" hover = { false } >
122- < div className = "overflow-x-auto" >
123- < table className = "w-full text-sm text-left" >
124- < caption className = "sr-only" > Competitor Library Comparison</ caption >
125- < thead >
126- < tr className = "border-b border-white/[0.06]" >
127- < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Library</ th >
128- < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Language</ th >
129- < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Ops/sec</ th >
130- < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Memory/op</ th >
131- < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Zero-copy</ th >
132- </ tr >
133- </ thead >
134- < tbody >
135- < tr className = "border-b border-white/[0.04] transition-colors bg-indigo-500/10 border-l-2 border-l-indigo-500" >
136- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-white font-medium" >
137- GoSQLX{ ' ' }
138- < span className = "ml-2 inline-block rounded-full bg-indigo-500/20 px-2 py-0.5 text-xs font-medium text-indigo-300" >
139- This Library
140- </ span >
141- </ td >
142- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400" > Go</ td >
143- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-mono" > 1.38M+</ td >
144- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-300" > Low</ td >
145- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-accent-green font-medium" >
146- < span aria-label = "Yes" > ✓</ span >
147- </ td >
148- </ tr >
149- < tr className = "border-b border-white/[0.04] hover:bg-white/[0.03] transition-colors" >
150- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-medium" > xwb1989/sqlparser</ td >
151- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400" > Go</ td >
152- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400 font-mono" > ~380K</ td >
153- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400" > Higher</ td >
154- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-500" >
155- < span aria-label = "No" > ✗</ span >
156- </ td >
157- </ tr >
158- < tr className = "border-b border-white/[0.04] hover:bg-white/[0.03] transition-colors" >
159- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-medium" > pg_query_go</ td >
160- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400" > Go</ td >
161- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400 font-mono" > ~220K</ td >
162- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400" > Higher (CGo)</ td >
163- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-500" >
164- < span aria-label = "No" > ✗</ span >
165- </ td >
166- </ tr >
167- < tr className = "border-b border-white/[0.04] hover:bg-white/[0.03] transition-colors" >
168- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-medium" > blastrain/sqlparser</ td >
169- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400" > Go</ td >
170- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400 font-mono" > ~290K</ td >
171- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400" > Medium</ td >
172- < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-500" >
173- < span aria-label = "No" > ✗</ span >
174- </ td >
175- </ tr >
176- </ tbody >
177- </ table >
178- </ div >
162+ < GlassCard className = "p-6" hover = { false } >
163+ < CompetitorChart />
179164 </ GlassCard >
180- < p className = "text-xs text-zinc-500 mt-2 md:hidden" > ← Swipe to see all columns →</ p >
181- < p className = "text-xs text-zinc-500 mt-2" > * Competitor figures estimated from published benchmarks on equivalent hardware. Results may vary by query complexity.</ p >
165+
166+ < RawDataToggle id = "competitor" >
167+ < GlassCard className = "p-0 overflow-hidden" hover = { false } >
168+ < div className = "overflow-x-auto" >
169+ < table className = "w-full text-sm text-left" >
170+ < caption className = "sr-only" > Competitor Library Comparison</ caption >
171+ < thead >
172+ < tr className = "border-b border-white/[0.06]" >
173+ < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Library</ th >
174+ < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Language</ th >
175+ < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Ops/sec</ th >
176+ < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Memory/op</ th >
177+ < th scope = "col" className = "px-3 py-3 sm:px-6 sm:py-4 font-medium text-zinc-400" > Zero-copy</ th >
178+ </ tr >
179+ </ thead >
180+ < tbody >
181+ < tr className = "border-b border-white/[0.04] transition-colors bg-indigo-500/10 border-l-2 border-l-indigo-500" >
182+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-white font-medium" >
183+ GoSQLX{ ' ' }
184+ < span className = "ml-2 inline-block rounded-full bg-indigo-500/20 px-2 py-0.5 text-xs font-medium text-indigo-300" >
185+ This Library
186+ </ span >
187+ </ td >
188+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400" > Go</ td >
189+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-mono" > 1.38M+</ td >
190+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-300" > Low</ td >
191+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-accent-green font-medium" >
192+ < span aria-label = "Yes" > { '\u2713' } </ span >
193+ </ td >
194+ </ tr >
195+ < tr className = "border-b border-white/[0.04] hover:bg-white/[0.03] transition-colors" >
196+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-medium" > xwb1989/sqlparser</ td >
197+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400" > Go</ td >
198+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400 font-mono" > ~380K</ td >
199+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400" > Higher</ td >
200+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-500" >
201+ < span aria-label = "No" > { '\u2717' } </ span >
202+ </ td >
203+ </ tr >
204+ < tr className = "border-b border-white/[0.04] hover:bg-white/[0.03] transition-colors" >
205+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-medium" > pg_query_go</ td >
206+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400" > Go</ td >
207+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400 font-mono" > ~220K</ td >
208+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400" > Higher (CGo)</ td >
209+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-500" >
210+ < span aria-label = "No" > { '\u2717' } </ span >
211+ </ td >
212+ </ tr >
213+ < tr className = "border-b border-white/[0.04] hover:bg-white/[0.03] transition-colors" >
214+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-300 font-medium" > blastrain/sqlparser</ td >
215+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400" > Go</ td >
216+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400 font-mono" > ~290K</ td >
217+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-400" > Medium</ td >
218+ < td className = "px-3 py-3 sm:px-6 sm:py-4 text-zinc-500" >
219+ < span aria-label = "No" > { '\u2717' } </ span >
220+ </ td >
221+ </ tr >
222+ </ tbody >
223+ </ table >
224+ </ div >
225+ </ GlassCard >
226+ < p className = "text-xs text-zinc-500 mt-2 md:hidden" > ← Swipe to see all columns →</ p >
227+ </ RawDataToggle >
182228 </ FadeIn >
183229 </ div >
184230 </ section >
0 commit comments