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 FlatString
25 var flatstr_allocations
= 0
27 # Counts the number of allocations of FlatBuffer
28 var flatbuf_allocations
= 0
30 # Counts the number of allocations of Concat
31 var concat_allocations
= 0
33 # Counts the number of allocations of RopeBuffer
34 var ropebuf_allocations
= 0
36 # Counts the number of calls to property length
37 var length_calls
= new Counter[String]
39 # Counts the number of length calls that missed the cache
40 var length_cache_miss
= new Counter[String]
42 # Counts the number of call to index on a Text
43 var index_call
= new Counter[String]
45 # Count the number of times that an indexed access
46 # on a Concat caused a regeneration of the cache
47 var concat_cache_miss
= 0
49 # Distance between characters when looking for a character in a FlatString
50 var index_len
= new Counter[Int]
52 # Length (bytes) of the FlatString created by lib
53 var str_bytelen
= new Counter[Int]
55 # Counter of the times `bytelen` is called on FlatString
56 var bytelen_call
= new Counter[String]
58 # Counter of the times `bytepos` is called on each type of receiver
59 var position_call
= new Counter[String]
61 # Counter of the times `bytepos` is called on each type of receiver
62 var bytepos_call
= new Counter[String]
64 # Calls to the `first_byte` property of a FlatString
65 var first_byte_call
= 0
67 # Calls to the `last_byte` property of a FlatString
68 var last_byte_call
= 0
70 # Number of strings created with full length created
71 var str_full_created
= 0
73 private fun show_string_stats
do
79 print
"\t-FlatString = {flatstr_allocations}"
80 print
"\t-FlatBuffer = {flatbuf_allocations}"
81 print
"\t-Concat = {concat_allocations}"
82 print
"\t-RopeBuffer = {ropebuf_allocations}"
84 print
"Calls to length, by type:"
85 for k
, v
in length_calls
do
87 if k
== "FlatString" then printn
" (cache misses {length_cache_miss[k]}, {div(length_cache_miss[k] * 100, v)}%)"
90 print
"Indexed accesses, by type:"
91 for k
, v
in index_call
do
93 if k
== "Concat" then printn
" (cache misses {concat_cache_miss}, {div(concat_cache_miss * 100, v)}%)"
97 print
"Calls to bytelen for each type:"
98 for k
, v
in bytelen_call
do
102 print
"Calls to position for each type:"
103 for k
, v
in position_call
do
107 print
"Calls to bytepos for each type:"
108 for k
, v
in bytepos_call
do
112 print
"Calls to first_byte on FlatString {first_byte_call}"
113 print
"Calls to last_byte on FlatString {last_byte_call}"
115 print
"FlatStrings allocated with length {str_full_created} ({str_full_created.to_f/flatstr_allocations.to_f * 100.0 }%)"
117 print
"Length of travel for index distribution:"
118 index_len
.print_content
120 print
"Byte length of the FlatStrings created:"
121 str_bytelen
.print_content
137 sys
.concat_allocations
+= 1
141 sys
.bytelen_call
.inc
"Concat"
146 sys
.index_call
.inc
"Concat"
147 if flat_last_pos_start
!= -1 then
148 var fsp
= i
- flat_last_pos_start
149 if fsp
>= 0 and fsp
< flat_cache
.length
then return flat_cache
[fsp
]
151 sys
.concat_cache_miss
+= 1
155 if s
isa FlatString then break
158 var llen
= lft
.length
166 flat_last_pos_start
= st
- i
173 redef fun char_to_byte_index
(index
) do
178 # Find best insertion point
179 var delta_begin
= index
180 var delta_end
= (ln
- 1) - index
181 var delta_cache
= (position
- index
).abs
182 var min
= delta_begin
185 if delta_cache
< min
then min
= delta_cache
186 if delta_end
< min
then min
= delta_end
191 if min
== delta_begin
then
194 else if min
== delta_cache
then
198 ns_i
= its
.find_beginning_of_char_at
(last_byte
)
204 ns_i
= its
.char_to_byte_index_cached
(index
, my_i
, ns_i
)
208 sys
.index_len
.inc
((after
- from
).abs
)
217 redef class RopeBuffer
219 sys
.ropebuf_allocations
+= 1
223 sys
.bytelen_call
.inc
"RopeBuffer"
228 sys
.index_call
.inc
"RopeBuffer"
233 redef class FlatBuffer
236 sys
.flatbuf_allocations
+= 1
240 sys
.bytepos_call
.inc
"FlatBuffer"
244 redef fun bytepos
=(p
) do
245 sys
.bytepos_call
.inc
"FlatBuffer"
249 redef fun position
do
250 sys
.position_call
.inc
"FlatBuffer"
254 redef fun position
=(p
) do
255 sys
.position_call
.inc
"FlatBuffer"
260 sys
.bytelen_call
.inc
"FlatBuffer"
265 sys
.length_calls
.inc
"FlatBuffer"
270 sys
.index_call
.inc
"FlatBuffer"
274 redef fun char_to_byte_index
(i
) do
275 sys
.index_call
.inc
"FlatBuffer"
280 redef class FlatString
283 sys
.bytepos_call
.inc
"FlatString"
287 redef fun bytepos
=(p
) do
288 sys
.bytepos_call
.inc
"FlatString"
292 redef fun position
do
293 sys
.position_call
.inc
"FlatString"
297 redef fun position
=(p
) do
298 sys
.position_call
.inc
"FlatString"
303 sys
.bytelen_call
.inc
"FlatString"
307 redef fun first_byte
do
308 sys
.first_byte_call
+= 1
312 redef fun first_byte
=(v
) do
313 sys
.first_byte_call
+= 1
317 redef fun last_byte
do
318 sys
.last_byte_call
+= 1
322 redef fun last_byte
=(v
) do
323 sys
.last_byte_call
+= 1
328 sys
.flatstr_allocations
+= 1
331 redef init with_infos
(items
, bytelen
, from
, to
)
334 self.bytelen
= bytelen
335 sys
.str_bytelen
.inc bytelen
340 redef init full
(items
, bytelen
, from
, to
, length
)
344 self.bytelen
= bytelen
345 sys
.str_bytelen
.inc bytelen
346 sys
.str_full_created
+= 1
351 private var length_cache
: nullable Int = null
354 sys
.length_calls
.inc
"FlatString"
356 if l
!= null then return l
357 sys
.length_cache_miss
.inc
"FlatString"
358 if bytelen
== 0 then return 0
364 st
+= its
.length_of_char_at
(st
)
371 redef fun char_to_byte_index
(i
) do
372 sys
.index_call
.inc
"FlatString"