Skip to content

Commit fdfce74

Browse files
authored
Optimize find_by_kind which turned out to be quite slow when generating bindings for opencv. These changes improved performance by 25%. (#100)
1 parent d97324c commit fdfce74

3 files changed

Lines changed: 15 additions & 9 deletions

File tree

lib/ffi/clang/cursor.rb

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# Copyright, 2022, by Motonori Iwamuro.
1414
# Copyright, 2023-2025, by Charlie Savage.
1515

16+
require "set"
1617
require_relative "lib/cursor"
1718
require_relative "lib/code_completion"
1819

@@ -477,20 +478,21 @@ def ancestors_by_kind(*kinds)
477478
# Find child cursors by kind.
478479
# @parameter recurse [Boolean | Nil] Whether to recurse into children.
479480
# @parameter kinds [Array(Symbol)] The cursor kinds to search for.
480-
# @returns [Array(Cursor)] Array of matching cursors.
481+
# @yields {|cursor| ...} Each matching cursor if a block is given.
482+
# @returns [Enumerator] If no block is given.
481483
# @raises [RuntimeError] If recurse parameter is not nil or boolean.
482-
def find_by_kind(recurse, *kinds)
484+
def find_by_kind(recurse, *kinds, &block)
483485
unless (recurse == nil || recurse == true || recurse == false)
484486
raise("Recurse parameter must be nil or a boolean value. Value was: #{recurse}")
485487
end
486488

487-
result = Array.new
489+
return enum_for(__method__, recurse, *kinds) unless block_given?
490+
491+
kinds_set = kinds.to_set
492+
488493
self.each(recurse) do |child, parent|
489-
if kinds.include?(child.kind)
490-
result << child
491-
end
494+
yield child if kinds_set.include?(child.kind)
492495
end
493-
result
494496
end
495497

496498
# Find all references to this cursor in a file.

releases.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Releases
22

3+
## v0.15.0
4+
5+
- {ruby FFI::Clang::Cursor\#find\_by\_kind} now returns an `Enumerator` instead of an `Array` when called without a block. This is a *breaking* change. Call `.to_a` if you need array indexing.
6+
37
## v0.14.0
48

5-
- Helper method that returns a curors's {ruby FFI::Clang::Cursor\#qualified\_display\_name}.
9+
- Helper method that returns a cursor's {ruby FFI::Clang::Cursor\#qualified\_display\_name}.

spec/spec_helper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def fixture_path(path)
2121
end
2222

2323
def find_all_by_kind(cursor, kind)
24-
cursor.find_by_kind(true, kind)
24+
cursor.find_by_kind(true, kind).to_a
2525
end
2626

2727
def find_by_kind(cursor, kind)

0 commit comments

Comments
 (0)