1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # This file is free software, which comes along with NIT. This software is
4 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
5 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
6 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
7 # is kept unaltered, and a notification of the changes is added.
8 # You are allowed to redistribute it and sell it, alone or is a part of
11 # Injects stat-calculating functionalities to Text and its variants
13 # Every allocation is counted for each available type of Text in Core
15 # Cached operations are monitored and statistics of their use are printed
16 # at the end of the execution of a program
19 intrude import core
::text
::ropes
24 # Counts the number of allocations of UnicodeFlatString
25 var uniflatstr_allocations
= 0
27 # Counts the number of allocations of ASCIIFlatString
28 var asciiflatstr_allocations
= 0
30 # Counts the number of allocations of FlatBuffer
31 var flatbuf_allocations
= 0
33 # Counts the number of allocations of Concat
34 var concat_allocations
= 0
36 # Counts the number of allocations of RopeBuffer
37 var ropebuf_allocations
= 0
39 # Counts the number of calls to property length
40 var length_calls
= new Counter[String]
42 # Counts the number of length calls that missed the cache
43 var length_cache_miss
= new Counter[String]
45 # Counts the number of call to index on a Text
46 var index_call
= new Counter[String]
48 # Count the number of times that an indexed access
49 # on a Concat caused a regeneration of the cache
50 var concat_cache_miss
= 0
52 # Distance between characters when looking for a character in a FlatString
53 var index_len
= new Counter[Int]
55 # Length (bytes) of the FlatString created by lib
56 var str_byte_length
= new Counter[Int]
58 # Counter of the times `byte_length` is called on FlatString
59 var byte_length_call
= new Counter[String]
61 # Counter of the times `bytepos` is called on each type of receiver
62 var position_call
= new Counter[String]
64 # Counter of the times `bytepos` is called on each type of receiver
65 var bytepos_call
= new Counter[String]
67 # Calls to the `first_byte` property of a FlatString
68 var first_byte_call
= 0
70 # Calls to the `last_byte` property of a FlatString
71 var last_byte_call
= 0
73 # Number of strings created with full length created
74 var str_full_created
= 0
76 private fun show_string_stats
do
82 print
"\t-UnicodeFlatString = {uniflatstr_allocations}"
83 print
"\t-ASCIIFlatString = {asciiflatstr_allocations}"
84 print
"\t-FlatBuffer = {flatbuf_allocations}"
85 print
"\t-Concat = {concat_allocations}"
86 print
"\t-RopeBuffer = {ropebuf_allocations}"
88 print
"Calls to length, by type:"
89 for k
, v
in length_calls
do
91 if k
== "UnicodeFlatString" then printn
" (cache misses {length_cache_miss[k]}, {div(length_cache_miss[k] * 100, v)}%)"
94 print
"Indexed accesses, by type:"
95 for k
, v
in index_call
do
97 if k
== "Concat" then printn
" (cache misses {concat_cache_miss}, {div(concat_cache_miss * 100, v)}%)"
101 print
"Calls to byte_length for each type:"
102 for k
, v
in byte_length_call
do
106 print
"Calls to position for each type:"
107 for k
, v
in position_call
do
111 print
"Calls to bytepos for each type:"
112 for k
, v
in bytepos_call
do
116 print
"Calls to first_byte on FlatString {first_byte_call}"
117 print
"Calls to last_byte on FlatString {last_byte_call}"
119 print
"Length of travel for index distribution:"
120 index_len
.print_content
122 print
"Byte length of the FlatStrings created:"
123 str_byte_length
.print_content
139 sys
.concat_allocations
+= 1
142 redef fun byte_length
do
143 sys
.byte_length_call
.inc
"Concat"
148 sys
.index_call
.inc
"Concat"
149 if flat_last_pos_start
!= -1 then
150 var fsp
= i
- flat_last_pos_start
151 if fsp
>= 0 and fsp
< flat_cache
.length
then return flat_cache
[fsp
]
153 sys
.concat_cache_miss
+= 1
157 if s
isa FlatString then break
160 var llen
= lft
.length
168 flat_last_pos_start
= st
- i
175 redef fun char_to_byte_index
(index
) do
180 # Find best insertion point
181 var delta_begin
= index
182 var delta_end
= (ln
- 1) - index
183 var delta_cache
= (position
- index
).abs
184 var min
= delta_begin
187 if delta_cache
< min
then min
= delta_cache
188 if delta_end
< min
then min
= delta_end
193 if min
== delta_begin
then
196 else if min
== delta_cache
then
200 ns_i
= its
.find_beginning_of_char_at
(last_byte
)
206 ns_i
= its
.char_to_byte_index_cached
(index
, my_i
, ns_i
)
210 sys
.index_len
.inc
((after
- from
).abs
)
219 redef class RopeBuffer
221 sys
.ropebuf_allocations
+= 1
224 redef fun byte_length
do
225 sys
.byte_length_call
.inc
"RopeBuffer"
230 sys
.index_call
.inc
"RopeBuffer"
235 redef class FlatBuffer
238 sys
.flatbuf_allocations
+= 1
242 sys
.bytepos_call
.inc
"FlatBuffer"
246 redef fun bytepos
=(p
) do
247 sys
.bytepos_call
.inc
"FlatBuffer"
251 redef fun position
do
252 sys
.position_call
.inc
"FlatBuffer"
256 redef fun position
=(p
) do
257 sys
.position_call
.inc
"FlatBuffer"
261 redef fun byte_length
do
262 sys
.byte_length_call
.inc
"FlatBuffer"
267 sys
.length_calls
.inc
"FlatBuffer"
272 sys
.index_call
.inc
"FlatBuffer"
276 redef fun char_to_byte_index
(i
) do
277 sys
.index_call
.inc
"FlatBuffer"
282 redef class FlatString
285 sys
.bytepos_call
.inc
"FlatString"
289 redef fun bytepos
=(p
) do
290 sys
.bytepos_call
.inc
"FlatString"
294 redef fun position
do
295 sys
.position_call
.inc
"FlatString"
299 redef fun position
=(p
) do
300 sys
.position_call
.inc
"FlatString"
304 redef fun byte_length
do
305 sys
.byte_length_call
.inc
"FlatString"
309 redef fun first_byte
do
310 sys
.first_byte_call
+= 1
314 redef fun first_byte
=(v
) do
315 sys
.first_byte_call
+= 1
319 redef fun last_byte
do
320 sys
.last_byte_call
+= 1
324 private var length_cache
: nullable Int = null
327 sys
.length_calls
.inc
"FlatString"
329 if l
!= null then return l
330 sys
.length_cache_miss
.inc
"FlatString"
331 if byte_length
== 0 then return 0
337 st
+= its
.length_of_char_at
(st
)
344 redef fun char_to_byte_index
(i
) do
345 sys
.index_call
.inc
"FlatString"
350 redef class ASCIIFlatString
351 redef init full_data
(items
, byte_length
, from
, length
)
354 sys
.asciiflatstr_allocations
+= 1
355 sys
.str_full_created
+= 1
359 redef class UnicodeFlatString
360 redef init full_data
(items
, byte_length
, from
, length
)
363 sys
.uniflatstr_allocations
+= 1
364 sys
.str_full_created
+= 1