@@ -79,37 +79,65 @@ fn guest_call_benchmark(c: &mut Criterion) {
7979 group. finish ( ) ;
8080}
8181
82- fn guest_call_benchmark_large_param ( c : & mut Criterion ) {
82+ fn guest_call_benchmark_large_params ( c : & mut Criterion ) {
8383 let mut group = c. benchmark_group ( "guest_functions_with_large_parameters" ) ;
8484 #[ cfg( target_os = "windows" ) ]
8585 group. sample_size ( 10 ) ; // This benchmark is very slow on Windows, so we reduce the sample size to avoid long test runs.
8686
87- // This benchmark includes time to first clone a vector and string, so it is not a "pure' benchmark of the guest call, but it's still useful
88- group. bench_function ( "guest_call_with_large_parameters" , |b| {
89- const SIZE : usize = 50 * 1024 * 1024 ; // 50 MB
90- let large_vec = vec ! [ 0u8 ; SIZE ] ;
91- let large_string = unsafe { String :: from_utf8_unchecked ( large_vec. clone ( ) ) } ; // Safety: indeed above vec is valid utf8
87+ // Helper function to create a benchmark for a specific size
88+ let create_benchmark = |group : & mut criterion:: BenchmarkGroup < _ > , size_mb : usize | {
89+ let benchmark_name = format ! ( "guest_call_with_2_large_parameters_{}mb each" , size_mb) ;
90+ group. bench_function ( & benchmark_name, |b| {
91+ let size = size_mb * 1024 * 1024 ; // Convert MB to bytes
92+ let large_vec = vec ! [ 0u8 ; size] ;
93+ let large_string = unsafe { String :: from_utf8_unchecked ( large_vec. clone ( ) ) } ; // Safety: indeed above vec is valid utf8
9294
93- let mut config = SandboxConfiguration :: default ( ) ;
94- config. set_input_data_size ( 2 * SIZE + ( 1024 * 1024 ) ) ; // 2 * SIZE + 1 MB, to allow 1MB for the rest of the serialized function call
95- config. set_heap_size ( SIZE as u64 * 15 ) ;
95+ let mut config = SandboxConfiguration :: default ( ) ;
96+ config. set_input_data_size ( 2 * size + ( 1024 * 1024 ) ) ;
9697
97- let sandbox = UninitializedSandbox :: new (
98- GuestBinary :: FilePath ( simple_guest_as_string ( ) . unwrap ( ) ) ,
99- Some ( config) ,
100- )
101- . unwrap ( ) ;
102- let mut sandbox = sandbox. evolve ( Noop :: default ( ) ) . unwrap ( ) ;
98+ if size < 50 * 1024 * 1024 {
99+ config. set_heap_size ( size as u64 * 16 ) ;
100+ } else {
101+ config. set_heap_size ( size as u64 * 11 ) ; // Set to 1GB for larger sizes
102+ }
103103
104- b. iter ( || {
105- sandbox
106- . call_guest_function_by_name :: < ( ) > (
107- "LargeParameters" ,
108- ( large_vec. clone ( ) , large_string. clone ( ) ) ,
109- )
110- . unwrap ( )
104+ let sandbox = UninitializedSandbox :: new (
105+ GuestBinary :: FilePath ( simple_guest_as_string ( ) . unwrap ( ) ) ,
106+ Some ( config) ,
107+ )
108+ . unwrap ( ) ;
109+ let mut sandbox = sandbox. evolve ( Noop :: default ( ) ) . unwrap ( ) ;
110+
111+ b. iter_custom ( |iters| {
112+ let mut total_duration = std:: time:: Duration :: new ( 0 , 0 ) ;
113+
114+ for _ in 0 ..iters {
115+ // Clone the data (not measured)
116+ let vec_clone = large_vec. clone ( ) ;
117+ let string_clone = large_string. clone ( ) ;
118+
119+ // Measure only the guest function call
120+ let start = std:: time:: Instant :: now ( ) ;
121+ sandbox
122+ . call_guest_function_by_name :: < ( ) > (
123+ "LargeParameters" ,
124+ ( vec_clone, string_clone) ,
125+ )
126+ . unwrap ( ) ;
127+ total_duration += start. elapsed ( ) ;
128+ }
129+
130+ total_duration
131+ } ) ;
111132 } ) ;
112- } ) ;
133+ } ;
134+
135+ // Create benchmarks for different sizes
136+ create_benchmark ( & mut group, 5 ) ; // 5MB
137+ create_benchmark ( & mut group, 10 ) ; // 10MB
138+ create_benchmark ( & mut group, 20 ) ; // 20MB
139+ create_benchmark ( & mut group, 40 ) ; // 40MB
140+ create_benchmark ( & mut group, 60 ) ; // 60MB
113141
114142 group. finish ( ) ;
115143}
@@ -153,9 +181,143 @@ fn sandbox_benchmark(c: &mut Criterion) {
153181 group. finish ( ) ;
154182}
155183
184+ fn sandbox_heap_size_benchmark ( c : & mut Criterion ) {
185+ let mut group = c. benchmark_group ( "sandbox_heap_sizes" ) ;
186+
187+ // Helper function to create sandbox with specific heap size
188+ let create_sandbox_with_heap_size = |heap_size_mb : Option < u64 > | {
189+ let path = simple_guest_as_string ( ) . unwrap ( ) ;
190+ let config = if let Some ( size_mb) = heap_size_mb {
191+ let mut config = SandboxConfiguration :: default ( ) ;
192+ config. set_heap_size ( size_mb * 1024 * 1024 ) ; // Convert MB to bytes
193+ Some ( config)
194+ } else {
195+ None
196+ } ;
197+
198+ let uninit_sandbox =
199+ UninitializedSandbox :: new ( GuestBinary :: FilePath ( path) , config) . unwrap ( ) ;
200+ uninit_sandbox. evolve ( Noop :: default ( ) ) . unwrap ( )
201+ } ;
202+
203+ // Benchmark sandbox creation with default heap size
204+ group. bench_function ( "create_sandbox_default_heap" , |b| {
205+ b. iter_with_large_drop ( || create_sandbox_with_heap_size ( None ) ) ;
206+ } ) ;
207+
208+ // Benchmark sandbox creation with 50MB heap
209+ group. bench_function ( "create_sandbox_50mb_heap" , |b| {
210+ b. iter_with_large_drop ( || create_sandbox_with_heap_size ( Some ( 50 ) ) ) ;
211+ } ) ;
212+
213+ // Benchmark sandbox creation with 100MB heap
214+ group. bench_function ( "create_sandbox_100mb_heap" , |b| {
215+ b. iter_with_large_drop ( || create_sandbox_with_heap_size ( Some ( 100 ) ) ) ;
216+ } ) ;
217+
218+ // Benchmark sandbox creation with 250MB heap
219+ group. bench_function ( "create_sandbox_250mb_heap" , |b| {
220+ b. iter_with_large_drop ( || create_sandbox_with_heap_size ( Some ( 250 ) ) ) ;
221+ } ) ;
222+
223+ // Benchmark sandbox creation with 500MB heap
224+ group. bench_function ( "create_sandbox_500mb_heap" , |b| {
225+ b. iter_with_large_drop ( || create_sandbox_with_heap_size ( Some ( 500 ) ) ) ;
226+ } ) ;
227+
228+ // Benchmark sandbox creation with 995MB heap (close to the limit of 1GB for a Sandbox )
229+ group. bench_function ( "create_sandbox_995mb_heap" , |b| {
230+ b. iter_with_large_drop ( || create_sandbox_with_heap_size ( Some ( 995 ) ) ) ;
231+ } ) ;
232+
233+ group. finish ( ) ;
234+ }
235+
236+ fn guest_call_heap_size_benchmark ( c : & mut Criterion ) {
237+ let mut group = c. benchmark_group ( "guest_call_heap_sizes" ) ;
238+
239+ // Helper function to create sandbox with specific heap size
240+ let create_sandbox_with_heap_size = |heap_size_mb : Option < u64 > | {
241+ let path = simple_guest_as_string ( ) . unwrap ( ) ;
242+ let config = if let Some ( size_mb) = heap_size_mb {
243+ let mut config = SandboxConfiguration :: default ( ) ;
244+ config. set_heap_size ( size_mb * 1024 * 1024 ) ; // Convert MB to bytes
245+ Some ( config)
246+ } else {
247+ None
248+ } ;
249+
250+ let uninit_sandbox =
251+ UninitializedSandbox :: new ( GuestBinary :: FilePath ( path) , config) . unwrap ( ) ;
252+ uninit_sandbox. evolve ( Noop :: default ( ) ) . unwrap ( )
253+ } ;
254+
255+ // Benchmark guest function call with default heap size
256+ group. bench_function ( "guest_call_default_heap" , |b| {
257+ let mut sandbox = create_sandbox_with_heap_size ( None ) ;
258+ b. iter ( || {
259+ sandbox
260+ . call_guest_function_by_name :: < String > ( "Echo" , "hello\n " . to_string ( ) )
261+ . unwrap ( )
262+ } ) ;
263+ } ) ;
264+
265+ // Benchmark guest function call with 50MB heap
266+ group. bench_function ( "guest_call_50mb_heap" , |b| {
267+ let mut sandbox = create_sandbox_with_heap_size ( Some ( 50 ) ) ;
268+ b. iter ( || {
269+ sandbox
270+ . call_guest_function_by_name :: < String > ( "Echo" , "hello\n " . to_string ( ) )
271+ . unwrap ( )
272+ } ) ;
273+ } ) ;
274+
275+ // Benchmark guest function call with 100MB heap
276+ group. bench_function ( "guest_call_100mb_heap" , |b| {
277+ let mut sandbox = create_sandbox_with_heap_size ( Some ( 100 ) ) ;
278+ b. iter ( || {
279+ sandbox
280+ . call_guest_function_by_name :: < String > ( "Echo" , "hello\n " . to_string ( ) )
281+ . unwrap ( )
282+ } ) ;
283+ } ) ;
284+
285+ // Benchmark guest function call with 250MB heap
286+ group. bench_function ( "guest_call_250mb_heap" , |b| {
287+ let mut sandbox = create_sandbox_with_heap_size ( Some ( 250 ) ) ;
288+ b. iter ( || {
289+ sandbox
290+ . call_guest_function_by_name :: < String > ( "Echo" , "hello\n " . to_string ( ) )
291+ . unwrap ( )
292+ } ) ;
293+ } ) ;
294+
295+ // Benchmark guest function call with 500MB heap
296+ group. bench_function ( "guest_call_500mb_heap" , |b| {
297+ let mut sandbox = create_sandbox_with_heap_size ( Some ( 500 ) ) ;
298+ b. iter ( || {
299+ sandbox
300+ . call_guest_function_by_name :: < String > ( "Echo" , "hello\n " . to_string ( ) )
301+ . unwrap ( )
302+ } ) ;
303+ } ) ;
304+
305+ // Benchmark guest function call with 995MB heap
306+ group. bench_function ( "guest_call_995mb_heap" , |b| {
307+ let mut sandbox = create_sandbox_with_heap_size ( Some ( 995 ) ) ;
308+ b. iter ( || {
309+ sandbox
310+ . call_guest_function_by_name :: < String > ( "Echo" , "hello\n " . to_string ( ) )
311+ . unwrap ( )
312+ } ) ;
313+ } ) ;
314+
315+ group. finish ( ) ;
316+ }
317+
156318criterion_group ! {
157319 name = benches;
158320 config = Criterion :: default ( ) ;
159- targets = guest_call_benchmark, sandbox_benchmark, guest_call_benchmark_large_param
321+ targets = guest_call_benchmark, sandbox_benchmark, sandbox_heap_size_benchmark , guest_call_benchmark_large_params , guest_call_heap_size_benchmark
160322}
161323criterion_main ! ( benches) ;
0 commit comments