No description
Find a file
NOT XVilka 80f14bf6fc
librz/util/vector: minor RzVector/RzPVector performance optimizations (#6467)
* util/vector: hoist quicksort scratch buffers out of the recursion

vector_quick_sort allocated its two element-sized scratch buffers (t and
pivot) with malloc/free on every recursive call. For a vector of n elements
the sort makes O(n) recursive calls, i.e. O(n) malloc/free pairs purely for
scratch space, and each call could also fail half-way through the sort.

Split the function into a small entry point that allocates the two buffers
once and a recursive worker that receives them as scratch. The buffers are
reused across the whole recursion (each partition step finishes using them
before recursing, and the recursion is sequential, so sharing one pair is
safe). Small elements -- the common case, including every RzPVector-backed
sort -- use stack buffers and allocate nothing at all; only elements larger
than 256 bytes fall back to a single heap allocation for the whole sort.

The element movement and rand()-based pivot selection are unchanged, so the
result is identical for any input (verified byte-for-byte against the previous
implementation for ascending and descending orders over many random arrays).

* util/vector: evaluate the comparator once per element in the quicksort

The partition loop tested the element against the pivot with two separate
calls to the comparator:

    if ((cmp(VEC_INDEX(a, i), pivot, user) < 0 && !reverse) ||
        (cmp(VEC_INDEX(a, i), pivot, user) > 0 && reverse)) {

Because cmp is an opaque function pointer the compiler cannot common up the
two calls, so depending on the result and the reverse flag the comparator was
invoked up to twice per element. Compute the result once into a local and test
that:

    int c = cmp(VEC_INDEX(a, i), pivot, user);
    if ((c < 0 && !reverse) || (c > 0 && reverse)) {

This halves comparator calls in the worst case and is a clear win whenever the
comparator is non-trivial (the common case for struct elements). Measured on a
shared host: ~12-14% faster for int sorting and ~30% faster with a moderately
expensive comparator. The ordering is unchanged (verified byte-for-byte).

* util/vector: simplify rz_pvector_remove_data index computation

The index of the located slot was computed as

    size_t index = (el - (void **)vec->v.a) * sizeof(void **) / vec->v.elem_size;

For an RzPVector the element size is always sizeof(void *), so the
`* sizeof(void **) / vec->v.elem_size` factor is identically 1 and the pointer
difference `el - (void **)vec->v.a` already yields the index directly. Drop the
redundant scaling, which removes a multiply and a divide and makes the intent
clear. Behaviour is unchanged.

* test/unit: add RzVector sort and rz_pvector_remove_data regression tests

The existing sort tests only sort 4-5 small elements and there was no test for
rz_pvector_remove_data. Add coverage for the code paths exercised by the sort
changes and the remove_data cleanup:

  - test_vector_sort_large       sort 2000 heavily-duplicated ut32 values
                                 ascending and descending, verifying the result
                                 is ordered and a permutation of the input (vs a
                                 reference qsort). Drives the recursion deeply
                                 and the shared scratch buffers.
  - test_vector_sort_large_elem  sort 400 elements of 304 bytes each, taking the
                                 heap-allocated scratch fallback, and check the
                                 full payload (not just the key) stays consistent
                                 through all the element moves.
  - test_pvector_remove_data     remove interior, first and last elements by
                                 value while preserving order, and confirm
                                 removing an absent value is a no-op.

All pass on both the previous and the optimized implementation (the sort and
remove_data changes are behaviour-preserving).

* test/bench: benchmark rz_vector_sort and rz_pvector_sort

bench_vector.c benchmarked only remove_at and swap. Add sort benchmarks so the
suite covers the functions touched by the sort optimizations and can be run
against the old and new librz for before/after numbers:

  - rz_vector_sort over 4k ut64 with a cheap comparator
  - rz_vector_sort over 4k ut64 with a deliberately expensive comparator
    (shows the effect of evaluating the comparator once per element)
  - rz_pvector_sort over 4k pointers (reference; pvector sort is unchanged)

Each iteration refills the buffer from an unsorted master copy via a single
memcpy before sorting; that overhead is identical across builds so the measured
delta reflects the sort.

---------

Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
2026-06-10 00:22:26 +08:00
.builds NetBSD: Upgrade to Python 3.10 (#5686) 2025-12-27 00:02:58 +08:00
.github Fix "gdbserver dp" test (#6424) 2026-05-30 07:14:18 +08:00
.woodpecker Run tests on woodpecker but be verbose. 2024-09-23 14:24:41 +08:00
binrz fix: remove windows debugger compilation warnings (#6140) 2026-04-05 16:27:46 +08:00
dist ci: fix macOS package creation 2026-02-01 20:29:59 +08:00
doc Add pf commands autocomplete (#6445) 2026-06-02 13:44:07 +08:00
examples Rename rz_list_first() / rz_list_last() to rz_list_first_val() / rz_list_last_val() (#5654) 2025-12-20 17:08:59 +08:00
librz librz/util/vector: minor RzVector/RzPVector performance optimizations (#6467) 2026-06-10 00:22:26 +08:00
LICENSES
patches Apply patches/fix_zydis_amalgamated_riscv32_build to subproject 2026-05-11 11:54:02 +08:00
subprojects Fix unused-but-set-variable 2026-06-01 01:45:59 +08:00
sys add RISC-V 32-bit env to CI (#6109) 2026-04-14 15:39:39 +08:00
test librz/util/vector: minor RzVector/RzPVector performance optimizations (#6467) 2026-06-10 00:22:26 +08:00
.appveyor.yml log.level help: Don't show 0:DEBUG on Release builds (#6319) 2026-05-07 22:33:46 +08:00
.clang-format Remove Language from .clang-format to reuse config for C & Cpp 2025-11-22 12:33:15 +08:00
.dockerignore
.git-blame-ignore-revs linter: update clang-format entries in .git-blame-ignore-revs (#5453) 2025-10-12 12:07:13 +08:00
.gitattributes
.gitignore hash: add jenkins non-cryptographic hash (#6121) 2026-04-02 01:42:23 +08:00
.lgtm.yml
.prettierignore
.pylintrc Add leak check in CI (#5553) 2025-12-04 11:02:01 +00:00
.travis.yml Fix endianness issues on s390x (#5940) 2026-02-19 23:13:18 +08:00
AGENTS.md Add AGENTS.md with requirement to disclose agent authorship and flag PRs with detected AI usage. (#6025) 2026-03-13 15:00:14 +00:00
BUILDING.md doc: fix various typos and documentation issues (#5771) 2026-01-10 21:33:54 +08:00
CODE_OF_CONDUCT.md
codecov.yml refactor: remove unused mpc subproject (#6091) 2026-03-25 20:30:15 +08:00
CODEOWNERS Simplify CODEOWNERS (#6040) 2026-03-15 15:52:16 +00:00
CONTRIBUTING.md Forbid usage of AI tools for good-first-issues. (#5829) 2026-01-23 13:06:24 +08:00
COPYING
COPYING.LESSER
DEVELOPERS.md Document allowed macro usage. (#6060) 2026-03-22 11:46:14 +00:00
Dockerfile Docker: Install zlib (#6444) 2026-05-31 21:03:16 +08:00
Doxyfile
meson.build Update Capstone and add M68k ColdFire support (#6399) 2026-05-31 16:15:56 +08:00
meson_options.txt blake2 hash support (#5995) 2026-03-06 22:17:59 +08:00
README.md rz-ar: add archive extraction utility (#6036) 2026-03-18 03:51:18 +08:00
REUSE.toml refactor: remove unused mpc subproject (#6091) 2026-03-25 20:30:15 +08:00
SECURITY.md Add AI tool guidelines (#5474) 2025-10-21 20:53:17 +08:00
snapcraft.yaml Bump version to v0.9.0 2025-04-23 16:49:14 +08:00
travis-extract-var.sh
travis-script Use meson setup <dir> instead of meson <dir> 2023-04-26 20:01:47 +08:00

Rizin logo

Rizin

Rizin is a reverse engineering framework, born as a fork of the radare2, with a focus on usability, features and cleanliness.

Rizin is portable and it can be used to analyze binaries, disassemble code, debug programs, as a forensic tool, as a scriptable command-line hexadecimal editor able to open disk files, and much more!

To learn more on Rizin you may want to read the official Rizin book.

How to install

Look at install instructions on our web page.

How to build

Use meson to compile and install Rizin. Please make sure to get an updated meson (e.g. get it with pip install meson if your system does not provide one that is at least version 0.55.0).

Clone this repository:

$ git clone https://github.com/rizinorg/rizin

Then compile and install with:

$ meson setup build
$ meson compile -C build
$ sudo meson install -C build

Now you can use rizin:

$ rizin
 -- Thank you for using rizin. Have a nice night!
[0x00000000]>

To uninstall rizin, execute sudo ninja -C build uninstall.

Please have a look at BUILDING.md for more information about building Rizin.

Contributing

We very much welcome any kind of contributions, from typos, to documentation, to refactoring, up to completely new features you may think of. Before contributing, we would like you to read the file CONTRIBUTING.md, so that we can all be on the same page.

Tests

Look at test/README.md.

Supported features

Supported Operating Systems

Windows 7 and higher, Apple macOS/iOS/iPadOS, GNU/Linux, [Dragonfly|Net|Free|Open]BSD, Android, QNX, Solaris/Illumos, Haiku, GNU/Darwin, GNU/Hurd.

Supported Architectures

i386, x86-64, ARM/ARM64, RISC-V, PowerPC, MIPS, AVR, SPARC, System Z (S390), SuperH, m68k, m680x, XAP, XCore, CR16, HPPA, ARC, Blackfin, Z80, H8/300, Renesas (V810, V850, RL78), CRIS, XAP, PIC, LM32, 8051, 6502, i4004, i8080, Propeller, Tricore, CHIP-8, LH5801, T8200, GameBoy, SNES, SPC700, MSP430, Xtensa, NIOS II, TMS320 (c54x, c55x, c55+, c64x), Hexagon, DCPU16, LANAI, MCORE, mcs96, RSP, C-SKY(MCore), VAX, AMD Am29000.

There is also support for the following bytecode formats:

Dalvik, EBC, Java, Lua, Python, WebAssembly, Brainfuck, Malbolge

Supported File Formats

ELF, Mach-O, Fatmach-O, PE, PE+, MZ, COFF, OMF, NE, LE, LX, TE, XBE, BIOS/UEFI, Dyldcache, DEX, ART, CGC, ELF, Java class, Android boot image, Plan9 executable, ZIMG, MBN/SBL bootloader, ELF coredump, MDMP (Windows minidump), DMP (Windows pagedump), WASM (WebAssembly binary), Commodore VICE emulator, QNX, Game Boy (Advance), Nintendo DS ROMs and Nintendo 3DS FIRMs.

Tools

Apart from the main tool rizin, there are also other tools tailored for specific purposes and useful for shell scripting or as separate standalone tools:

  • rz-bin - provides all kind of information about binary formats
  • rz-ar - list and extract members from static archives (.a and .lib)
  • rz-asm - a command-line assembler and disassemblers
  • rz-diff - a tool to compare two binaries as raw data or analyzed executables
  • rz-hash - allows to calculate different hashes or even encrypt data
  • rz-gg - a small "eggs" code generator useful for exploitation purposes
  • rz-find - binary analog of find tool, allowing to search patterns and bit masks
  • rz-sign - tool to create, convert and parse FLIRT signatures
  • rz-ax - a calculator and number format converter
  • rz-run - a tool that allows to specify running environment and arguments for debugged file

Scripting

We provide a way to interact with Rizin from Python, Haskell, OCaml, Ruby, Rust, and Go languages through rzpipe. Other languages although not currently supported could be easily added.

Community

Our website and blog: https://www.rizin.re/

Join our Mattermost community to discuss Rizin, its development, and general topics related to the project.

We also provide the following partial bridges to other messaging platforms: