-
Notifications
You must be signed in to change notification settings - Fork 88
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improved hex parsing speed for offsets, instruction pointers, and per…
…f maps with int64_of_hex_string. This addresses issue #93. Although #150 implemented fast hex string parsing, when I was magic-tracing magic-trace, I noticed this in the trace: This section of the trace entirely occurs because of calling `Int.Hex.of_string offset` within `parse_symbol_and_offset`. And this tends to take around 200-250 ns. Since this occurs about once per line in the `perf.data` file, the trace I ran this on executed this around 1.8 million times which should save a few hundred ms (out of total time of a few seconds). Here are the traces after and before this change (respectively) zoomed in on 3 decodes (which shows 3 executions of `parse_symbol_and_offset`) of a perf line containing an entry of the callstack sampled. The former is just below 2 us and the latter is around 2.6 us. However it is clear that most of the remaining time is now spent on evaluating regex in the former. In regards to implementation, I extracted these functions out to a `Util` module and used them when possible else where in magic-trace (although only the offset calculation is expensive because it is called a lot, but it seems reasonable to use them if possible). I used first class modules to abstract around `Int` and `Int64`. Signed-off-by: Aaron Lamoreaux <alamoreaux@janestreet.com>
- Loading branch information
1 parent
e614913
commit d578b37
Showing
5 changed files
with
80 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
open! Core | ||
|
||
let intable_of_hex_string | ||
(type a) | ||
(module M : Int_intf.S with type t = a) | ||
?(remove_hex_prefix = false) | ||
str | ||
= | ||
(* Bit hacks for fast parsing of hex strings. | ||
* | ||
* Note that in ASCII, ('1' | 'a' | 'A') & 0xF = 1. | ||
* | ||
* So for each character, take the bottom 4 bits, and add 9 if it's | ||
* not a digit. *) | ||
let res = ref (M.of_int_exn 0) in | ||
let fifteen = M.of_int_exn 0xF in | ||
let eight = M.of_int_exn 0x8 in | ||
for i = if remove_hex_prefix then 2 else 0 to String.length str - 1 do | ||
let open M in | ||
let c = of_int_exn (Char.to_int (String.unsafe_get str i)) in | ||
res := (!res lsl 4) lor ((c land fifteen) + ((c lsr 6) lor ((c lsr 3) land eight))) | ||
done; | ||
!res | ||
;; | ||
|
||
let int64_of_hex_string = intable_of_hex_string (module Int64) | ||
let int_of_hex_string = intable_of_hex_string (module Int) | ||
|
||
let%test_module _ = | ||
(module struct | ||
open Core | ||
|
||
let check ?remove_hex_prefix str = | ||
print_s | ||
[%message | ||
"" | ||
~int64:(int64_of_hex_string ?remove_hex_prefix str : Int64.Hex.t) | ||
~int:(int_of_hex_string ?remove_hex_prefix str : Int.Hex.t)] | ||
;; | ||
|
||
let%expect_test "int64 hex parsing" = | ||
check ~remove_hex_prefix:true "0x7f9db48c1d80"; | ||
[%expect {| | ||
((int64 0x7f9db48c1d80) (int 0x7f9db48c1d80)) |}]; | ||
check "7f9db48c1d80"; | ||
[%expect {| | ||
((int64 0x7f9db48c1d80) (int 0x7f9db48c1d80)) |}]; | ||
check "fF"; | ||
[%expect {| | ||
((int64 0xff) (int 0xff)) |}]; | ||
check "f0f"; | ||
[%expect {| | ||
((int64 0xf0f) (int 0xf0f)) |}]; | ||
check "fA0f"; | ||
[%expect {| | ||
((int64 0xfa0f) (int 0xfa0f)) |}]; | ||
check "0"; | ||
[%expect {| | ||
((int64 0x0) (int 0x0)) |}] | ||
;; | ||
end) | ||
;; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
open! Core | ||
|
||
val int64_of_hex_string : ?remove_hex_prefix:bool -> string -> int64 | ||
val int_of_hex_string : ?remove_hex_prefix:bool -> string -> int |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters