@@ -121,71 +121,92 @@ impl ProjectDatabase {
121121 ingredients. sort_by_key ( |ingredient| cmp:: Reverse ( ingredient. size_of_fields ( ) ) ) ;
122122 memos. sort_by_key ( |( _, memo) | cmp:: Reverse ( memo. size_of_fields ( ) ) ) ;
123123
124- SalsaMemoryDump { ingredients, memos }
124+ let mut total_fields = 0 ;
125+ let mut total_metadata = 0 ;
126+ for ingredient in & ingredients {
127+ total_metadata += ingredient. size_of_metadata ( ) ;
128+ total_fields += ingredient. size_of_fields ( ) ;
129+ }
130+
131+ let mut total_memo_fields = 0 ;
132+ let mut total_memo_metadata = 0 ;
133+ for ( _, memo) in & memos {
134+ total_memo_fields += memo. size_of_fields ( ) ;
135+ total_memo_metadata += memo. size_of_metadata ( ) ;
136+ }
137+
138+ SalsaMemoryDump {
139+ total_fields,
140+ total_metadata,
141+ total_memo_fields,
142+ total_memo_metadata,
143+ ingredients,
144+ memos,
145+ }
125146 }
126147}
127148
128149/// Stores memory usage information.
129150pub struct SalsaMemoryDump {
151+ total_fields : usize ,
152+ total_metadata : usize ,
153+ total_memo_fields : usize ,
154+ total_memo_metadata : usize ,
130155 ingredients : Vec < salsa:: IngredientInfo > ,
131156 memos : Vec < ( & ' static str , salsa:: IngredientInfo ) > ,
132157}
133158
134159#[ allow( clippy:: cast_precision_loss) ]
160+ fn bytes_to_mb ( total : usize ) -> f64 {
161+ total as f64 / 1_000_000.
162+ }
163+
164+ #[ allow( clippy:: cast_possible_truncation, clippy:: cast_sign_loss) ]
135165impl SalsaMemoryDump {
136166 /// Returns a short report that provides total memory usage information.
137167 pub fn display_short ( & self ) -> impl fmt:: Display + ' _ {
138168 struct DisplayShort < ' a > ( & ' a SalsaMemoryDump ) ;
139169
140170 impl fmt:: Display for DisplayShort < ' _ > {
141171 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
142- let mut total_fields = 0 ;
143- let mut total_metadata = 0 ;
144- for ingredient in & self . 0 . ingredients {
145- total_metadata += ingredient. size_of_metadata ( ) ;
146- total_fields += ingredient. size_of_fields ( ) ;
147- }
148-
149- let mut total_memo_fields = 0 ;
150- let mut total_memo_metadata = 0 ;
151- for ( _, memo) in & self . 0 . memos {
152- total_memo_fields += memo. size_of_fields ( ) ;
153- total_memo_metadata += memo. size_of_metadata ( ) ;
154- }
172+ let SalsaMemoryDump {
173+ total_fields,
174+ total_metadata,
175+ total_memo_fields,
176+ total_memo_metadata,
177+ ref ingredients,
178+ ref memos,
179+ } = * self . 0 ;
155180
156181 writeln ! ( f, "=======SALSA SUMMARY=======" ) ?;
157182
158183 writeln ! (
159184 f,
160185 "TOTAL MEMORY USAGE: {:.2}MB" ,
161- ( total_metadata + total_fields + total_memo_fields + total_memo_metadata )
162- as f64
163- / 1_000_000. ,
186+ bytes_to_mb (
187+ total_metadata + total_fields + total_memo_fields + total_memo_metadata
188+ )
164189 ) ?;
165190
166191 writeln ! (
167192 f,
168193 " struct metadata = {:.2}MB" ,
169- total_metadata as f64 / 1_000_000. ,
170- ) ?;
171- writeln ! (
172- f,
173- " struct fields = {:.2}MB" ,
174- total_fields as f64 / 1_000_000. ,
194+ bytes_to_mb( total_metadata) ,
175195 ) ?;
196+ writeln ! ( f, " struct fields = {:.2}MB" , bytes_to_mb( total_fields) ) ?;
176197 writeln ! (
177198 f,
178199 " memo metadata = {:.2}MB" ,
179- total_memo_metadata as f64 / 1_000_000. ,
200+ bytes_to_mb ( total_memo_metadata) ,
180201 ) ?;
181202 writeln ! (
182203 f,
183204 " memo fields = {:.2}MB" ,
184- total_memo_fields as f64 / 1_000_000.
205+ bytes_to_mb ( total_memo_fields) ,
185206 ) ?;
186207
187- writeln ! ( f, "QUERY COUNT: {}" , self . 0 . memos. len( ) ) ?;
188- writeln ! ( f, "STRUCT COUNT: {}" , self . 0 . ingredients. len( ) ) ?;
208+ writeln ! ( f, "QUERY COUNT: {}" , memos. len( ) ) ?;
209+ writeln ! ( f, "STRUCT COUNT: {}" , ingredients. len( ) ) ?;
189210
190211 Ok ( ( ) )
191212 }
@@ -201,39 +222,38 @@ impl SalsaMemoryDump {
201222
202223 impl fmt:: Display for DisplayFull < ' _ > {
203224 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
204- writeln ! ( f, "=======SALSA STRUCTS=======" ) ?;
225+ let SalsaMemoryDump {
226+ total_fields,
227+ total_metadata,
228+ total_memo_fields,
229+ total_memo_metadata,
230+ ref ingredients,
231+ ref memos,
232+ } = * self . 0 ;
205233
206- let mut total_fields = 0 ;
207- let mut total_metadata = 0 ;
208- for ingredient in & self . 0 . ingredients {
209- total_metadata += ingredient. size_of_metadata ( ) ;
210- total_fields += ingredient. size_of_fields ( ) ;
234+ writeln ! ( f, "=======SALSA STRUCTS=======" ) ?;
211235
236+ for ingredient in ingredients {
212237 writeln ! (
213238 f,
214239 "{:<50} metadata={:<8} fields={:<8} count={}" ,
215240 format!( "`{}`" , ingredient. debug_name( ) ) ,
216- format!( "{:.2}MB" , ingredient. size_of_metadata( ) as f64 / 1_000_000. ) ,
217- format!( "{:.2}MB" , ingredient. size_of_fields( ) as f64 / 1_000_000. ) ,
241+ format!( "{:.2}MB" , bytes_to_mb ( ingredient. size_of_metadata( ) ) ) ,
242+ format!( "{:.2}MB" , bytes_to_mb ( ingredient. size_of_fields( ) ) ) ,
218243 ingredient. count( )
219244 ) ?;
220245 }
221246
222247 writeln ! ( f, "=======SALSA QUERIES=======" ) ?;
223248
224- let mut total_memo_fields = 0 ;
225- let mut total_memo_metadata = 0 ;
226- for ( query_fn, memo) in & self . 0 . memos {
227- total_memo_fields += memo. size_of_fields ( ) ;
228- total_memo_metadata += memo. size_of_metadata ( ) ;
229-
249+ for ( query_fn, memo) in memos {
230250 writeln ! ( f, "`{query_fn} -> {}`" , memo. debug_name( ) ) ?;
231251
232252 writeln ! (
233253 f,
234254 " metadata={:<8} fields={:<8} count={}" ,
235- format!( "{:.2}MB" , memo. size_of_metadata( ) as f64 / 1_000_000. ) ,
236- format!( "{:.2}MB" , memo. size_of_fields( ) as f64 / 1_000_000. ) ,
255+ format!( "{:.2}MB" , bytes_to_mb ( memo. size_of_metadata( ) ) ) ,
256+ format!( "{:.2}MB" , bytes_to_mb ( memo. size_of_fields( ) ) ) ,
237257 memo. count( )
238258 ) ?;
239259 }
@@ -242,30 +262,26 @@ impl SalsaMemoryDump {
242262 writeln ! (
243263 f,
244264 "TOTAL MEMORY USAGE: {:.2}MB" ,
245- ( total_metadata + total_fields + total_memo_fields + total_memo_metadata )
246- as f64
247- / 1_000_000. ,
265+ bytes_to_mb (
266+ total_metadata + total_fields + total_memo_fields + total_memo_metadata
267+ )
248268 ) ?;
249269
250270 writeln ! (
251271 f,
252272 " struct metadata = {:.2}MB" ,
253- total_metadata as f64 / 1_000_000. ,
254- ) ?;
255- writeln ! (
256- f,
257- " struct fields = {:.2}MB" ,
258- total_fields as f64 / 1_000_000. ,
273+ bytes_to_mb( total_metadata) ,
259274 ) ?;
275+ writeln ! ( f, " struct fields = {:.2}MB" , bytes_to_mb( total_fields) ) ?;
260276 writeln ! (
261277 f,
262278 " memo metadata = {:.2}MB" ,
263- total_memo_metadata as f64 / 1_000_000. ,
279+ bytes_to_mb ( total_memo_metadata) ,
264280 ) ?;
265281 writeln ! (
266282 f,
267283 " memo fields = {:.2}MB" ,
268- total_memo_fields as f64 / 1_000_000.
284+ bytes_to_mb ( total_memo_fields) ,
269285 ) ?;
270286
271287 Ok ( ( ) )
@@ -274,6 +290,70 @@ impl SalsaMemoryDump {
274290
275291 DisplayFull ( self )
276292 }
293+
294+ /// Returns a redacted report that provides rounded totals of memory usage, to avoid
295+ /// overly sensitive diffs in `mypy-primer` runs.
296+ pub fn display_mypy_primer ( & self ) -> impl fmt:: Display + ' _ {
297+ struct DisplayShort < ' a > ( & ' a SalsaMemoryDump ) ;
298+
299+ fn round_memory ( total : usize ) -> usize {
300+ // Round the number to the nearest power of 1.1. This gives us a
301+ // 5% threshold before the memory usage number is considered to have
302+ // changed.
303+ //
304+ // TODO: Small changes in memory usage may cause the number to be rounded
305+ // into the next power if it happened to already be close to the threshold.
306+ // This also means that differences may surface as a result of small changes
307+ // over time that are unrelated to the current change. Ideally we could compare
308+ // the exact numbers across runs and compute the difference, but we don't have
309+ // the infrastructure for that currently.
310+ const BASE : f64 = 1.1 ;
311+ BASE . powf ( bytes_to_mb ( total) . log ( BASE ) . round ( ) ) as usize
312+ }
313+
314+ impl fmt:: Display for DisplayShort < ' _ > {
315+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
316+ let SalsaMemoryDump {
317+ total_fields,
318+ total_metadata,
319+ total_memo_fields,
320+ total_memo_metadata,
321+ ..
322+ } = * self . 0 ;
323+
324+ writeln ! ( f, "=======SALSA SUMMARY=======" ) ?;
325+
326+ writeln ! (
327+ f,
328+ "TOTAL MEMORY USAGE: ~{}MB" ,
329+ round_memory(
330+ total_metadata + total_fields + total_memo_fields + total_memo_metadata
331+ )
332+ ) ?;
333+
334+ writeln ! (
335+ f,
336+ " struct metadata = ~{}MB" ,
337+ round_memory( total_metadata)
338+ ) ?;
339+ writeln ! ( f, " struct fields = ~{}MB" , round_memory( total_fields) ) ?;
340+ writeln ! (
341+ f,
342+ " memo metadata = ~{}MB" ,
343+ round_memory( total_memo_metadata)
344+ ) ?;
345+ writeln ! (
346+ f,
347+ " memo fields = ~{}MB" ,
348+ round_memory( total_memo_fields)
349+ ) ?;
350+
351+ Ok ( ( ) )
352+ }
353+ }
354+
355+ DisplayShort ( self )
356+ }
277357}
278358
279359#[ salsa:: db]
0 commit comments