leptris 1.9.19 → 1.9.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97ca1201d65e8bb43ac419b09c9e208fd49a1cb88275beb14cb2f2ec0e7965e2
4
- data.tar.gz: df1b06279ae9426f463c724a6c895a135daedb19880f62ba1c8cda377228af3f
3
+ metadata.gz: 5b71e0f6fdc7eafc4b804bfc7006f7e15e11f8e1ebf2a403c440763bc1fe9cba
4
+ data.tar.gz: 3d7d98ef8818d1789afa83fbb9e5eff6bab040ef4838900bccd8213cb8404570
5
5
  SHA512:
6
- metadata.gz: 390e31d59b5fe74f08776d719e5cd608a6cee954184a65edd688d25e92ed019be47b39c65369a5553fe1b1425341570778b3f6a7abf5896ca425935cf1e3e2aa
7
- data.tar.gz: f72f7460afa8f16d0aa77e313d8d047c8ff1cf98180332c34f59c4034352fa737256cf943b1cecf941caee2ae7beddd1e0f844c1e2bb305332594f496b026d77
6
+ metadata.gz: a11ceae79c465f05002dd31e9af7a29d1b86194c45398f940523c4718f4e1695382b573557199dac34e8cc4aae1c39aa9faf430d6def6b6333f86f3973938393
7
+ data.tar.gz: d77c0a145409d9735b593e396b4e3a2d093cbc8011f5880510c2100fac2e2787cdff6977ba795e5b85ac2f1b6f837c17ff8b647a1e20dcdb3037cc3f08621c00
data/CHANGELOG.md CHANGED
@@ -5,6 +5,27 @@ All notable changes to Leptris will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.9.20] - 2026-08-27
9
+
10
+ ### Changed
11
+
12
+ - **Pull event loop allocation trim**: `Parser#next_event` reads the
13
+ event's type/name/text through layout-derived offsets
14
+ (`PullEventStruct.offset_of` — the struct stays the ABI's single
15
+ source of truth) instead of allocating a struct wrapper per event;
16
+ `capture_attrs` builds its hash without the enumerator machinery
17
+ and answers nil for zero attributes. Streaming a 300-element
18
+ document: 2.9 ms -> 2.3 ms per parse (**-20%**). The remaining
19
+ per-event cost is FFI dispatch — the batch ask is filed upstream
20
+ (leptris/leptris#589).
21
+
22
+ ### Meta
23
+
24
+ - Streaming-path benchmarks added to the round's report: pull with
25
+ events measured 145x slower than DOM-parsing the same bytes
26
+ (dispatch-dominated); iterparse's 60% system-time signature
27
+ documented on leptris/leptris#563 (C-side release churn).
28
+
8
29
  ## [1.9.19] - 2026-08-27
9
30
 
10
31
  Lockstep with libleptris 1.9.3 — unblocks the 1.9.18 release
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leptris
4
- VERSION = "1.9.19"
4
+ VERSION = "1.9.20"
5
5
  end
@@ -60,6 +60,14 @@ module Leptris::XML::Pull
60
60
  self
61
61
  end
62
62
 
63
+ # Hot-loop offsets: derived from PullEventStruct's layout (the
64
+ # struct stays the single source of truth for the ABI), read via
65
+ # get_int/get_pointer so the per-event struct-wrapper allocation
66
+ # disappears from streaming loops.
67
+ NAME_OFFSET = Leptris::XML::FFI::PullEventStruct.offset_of(:name)
68
+ TEXT_OFFSET = Leptris::XML::FFI::PullEventStruct.offset_of(:text)
69
+ private_constant :NAME_OFFSET, :TEXT_OFFSET
70
+
63
71
  # Advances the cursor and returns the next Event, or nil after the
64
72
  # end of the document. Attribute values are captured during
65
73
  # start_element because the C accessors are valid only for the
@@ -67,26 +75,31 @@ module Leptris::XML::Pull
67
75
  def next_event
68
76
  raw = Leptris::XML::FFI.leptris_pull_next(@handle)
69
77
  return nil if raw.null?
70
- event = Leptris::XML::FFI::PullEventStruct.new(raw)
71
- type = TYPES[event[:type]]
72
- name = read_owned(event[:name])
73
- text = read_owned(event[:text])
78
+ type = TYPES[raw.get_int(0)]
79
+ name_ptr = raw.get_pointer(NAME_OFFSET)
80
+ text_ptr = raw.get_pointer(TEXT_OFFSET)
74
81
  attrs = type == :start_element ? capture_attrs : nil
75
- Event.new(type: type, name: name, text: text, attrs: attrs)
82
+ Event.new(
83
+ type: type,
84
+ name: name_ptr.null? ? nil : name_ptr.read_string.force_encoding(Encoding::UTF_8),
85
+ text: text_ptr.null? ? nil : text_ptr.read_string.force_encoding(Encoding::UTF_8),
86
+ attrs: attrs
87
+ )
76
88
  end
77
89
 
78
90
  private
79
91
 
80
- def read_owned(ptr)
81
- ptr.null? ? nil : ptr.read_string.force_encoding(Encoding::UTF_8)
82
- end
83
-
84
92
  def capture_attrs
85
93
  count = Leptris::XML::FFI.leptris_pull_attr_count(@handle)
86
- count.times.each_with_object({}) do |i, hash|
94
+ return nil if count.zero?
95
+ hash = {}
96
+ i = 0
97
+ while i < count
87
98
  hash[Leptris::XML::FFI.leptris_pull_attr_name(@handle, i)] =
88
99
  Leptris::XML::FFI.leptris_pull_attr_value(@handle, i)
100
+ i += 1
89
101
  end
102
+ hash
90
103
  end
91
104
  end
92
105
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.19
4
+ version: 1.9.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.