xlsxrb 0.1.3 → 0.1.5

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.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/Dockerfile +2 -1
  3. data/.gem_rbs_collection/ast/2.4/.rbs_meta.yaml +9 -0
  4. data/.gem_rbs_collection/ast/2.4/ast.rbs +73 -0
  5. data/.gem_rbs_collection/concurrent-ruby/1.1/.rbs_meta.yaml +9 -0
  6. data/.gem_rbs_collection/concurrent-ruby/1.1/array.rbs +4 -0
  7. data/.gem_rbs_collection/concurrent-ruby/1.1/atomic_reference.rbs +16 -0
  8. data/.gem_rbs_collection/concurrent-ruby/1.1/executor.rbs +96 -0
  9. data/.gem_rbs_collection/concurrent-ruby/1.1/hash.rbs +4 -0
  10. data/.gem_rbs_collection/concurrent-ruby/1.1/map.rbs +68 -0
  11. data/.gem_rbs_collection/concurrent-ruby/1.1/promises.rbs +249 -0
  12. data/.gem_rbs_collection/concurrent-ruby/1.1/set.rbs +4 -0
  13. data/.gem_rbs_collection/concurrent-ruby/1.1/timer_task.rbs +47 -0
  14. data/.gem_rbs_collection/concurrent-ruby/1.1/utility/processor_counter.rbs +5 -0
  15. data/.gem_rbs_collection/csv/3.3/.rbs_meta.yaml +9 -0
  16. data/.gem_rbs_collection/csv/3.3/csv.rbs +3871 -0
  17. data/.gem_rbs_collection/csv/3.3/manifest.yaml +3 -0
  18. data/.gem_rbs_collection/lint_roller/1.1/.rbs_meta.yaml +9 -0
  19. data/.gem_rbs_collection/lint_roller/1.1/lint_roller.rbs +48 -0
  20. data/.gem_rbs_collection/listen/3.9/.rbs_meta.yaml +9 -0
  21. data/.gem_rbs_collection/listen/3.9/listen.rbs +25 -0
  22. data/.gem_rbs_collection/listen/3.9/listener.rbs +24 -0
  23. data/.gem_rbs_collection/logger/1.7/.rbs_meta.yaml +9 -0
  24. data/.gem_rbs_collection/logger/1.7/formatter.rbs +45 -0
  25. data/.gem_rbs_collection/logger/1.7/log_device.rbs +100 -0
  26. data/.gem_rbs_collection/logger/1.7/logger.rbs +796 -0
  27. data/.gem_rbs_collection/logger/1.7/manifest.yaml +2 -0
  28. data/.gem_rbs_collection/logger/1.7/period.rbs +17 -0
  29. data/.gem_rbs_collection/logger/1.7/severity.rbs +34 -0
  30. data/.gem_rbs_collection/parallel/1.20/.rbs_meta.yaml +9 -0
  31. data/.gem_rbs_collection/parallel/1.20/parallel.rbs +86 -0
  32. data/.gem_rbs_collection/parser/3.2/.rbs_meta.yaml +9 -0
  33. data/.gem_rbs_collection/parser/3.2/manifest.yaml +7 -0
  34. data/.gem_rbs_collection/parser/3.2/parser.rbs +194 -0
  35. data/.gem_rbs_collection/parser/3.2/polyfill.rbs +4 -0
  36. data/.gem_rbs_collection/rainbow/3.0/.rbs_meta.yaml +9 -0
  37. data/.gem_rbs_collection/rainbow/3.0/global.rbs +7 -0
  38. data/.gem_rbs_collection/rainbow/3.0/presenter.rbs +209 -0
  39. data/.gem_rbs_collection/rainbow/3.0/rainbow.rbs +5 -0
  40. data/.gem_rbs_collection/rake/13.0/.rbs_meta.yaml +9 -0
  41. data/.gem_rbs_collection/rake/13.0/manifest.yaml +2 -0
  42. data/.gem_rbs_collection/rake/13.0/rake.rbs +39 -0
  43. data/.gem_rbs_collection/regexp_parser/2.8/.rbs_meta.yaml +9 -0
  44. data/.gem_rbs_collection/regexp_parser/2.8/regexp_parser.rbs +17 -0
  45. data/.gem_rbs_collection/rubocop/1.57/.rbs_meta.yaml +9 -0
  46. data/.gem_rbs_collection/rubocop/1.57/rubocop.rbs +208 -0
  47. data/.gem_rbs_collection/rubocop-ast/1.46/.rbs_meta.yaml +9 -0
  48. data/.gem_rbs_collection/rubocop-ast/1.46/rubocop-ast.rbs +903 -0
  49. data/CHANGELOG.md +24 -3
  50. data/README.md +91 -17
  51. data/Rakefile +124 -89
  52. data/Steepfile +19 -0
  53. data/docs/ARCHITECTURE.md +17 -0
  54. data/docs/DEVELOPMENT.md +58 -0
  55. data/docs/QUALITY_ASSURANCE.md +26 -0
  56. data/docs/visual/VisualGallery.md +893 -938
  57. data/docs/wasm/ruby.wasm +0 -0
  58. data/lib/xlsxrb/elements/cell.rb +74 -1
  59. data/lib/xlsxrb/elements/column.rb +2 -0
  60. data/lib/xlsxrb/elements/row.rb +37 -2
  61. data/lib/xlsxrb/elements/types.rb +2 -0
  62. data/lib/xlsxrb/elements/workbook.rb +29 -0
  63. data/lib/xlsxrb/elements/worksheet.rb +98 -1
  64. data/lib/xlsxrb/elements.rb +2 -0
  65. data/lib/xlsxrb/ooxml/reader.rb +8 -6
  66. data/lib/xlsxrb/ooxml/shared_strings_parser.rb +2 -0
  67. data/lib/xlsxrb/ooxml/styles_parser.rb +2 -0
  68. data/lib/xlsxrb/ooxml/utils.rb +2 -0
  69. data/lib/xlsxrb/ooxml/workbook_parser.rb +6 -1
  70. data/lib/xlsxrb/ooxml/workbook_writer.rb +15 -4
  71. data/lib/xlsxrb/ooxml/worksheet_parser.rb +12 -0
  72. data/lib/xlsxrb/ooxml/worksheet_writer.rb +49 -9
  73. data/lib/xlsxrb/ooxml/writer.rb +217 -5
  74. data/lib/xlsxrb/ooxml/xml_builder.rb +2 -0
  75. data/lib/xlsxrb/ooxml/xml_parser.rb +2 -0
  76. data/lib/xlsxrb/ooxml/zip_generator.rb +5 -8
  77. data/lib/xlsxrb/ooxml/zip_reader.rb +88 -52
  78. data/lib/xlsxrb/ooxml/zip_writer.rb +2 -0
  79. data/lib/xlsxrb/ooxml.rb +3 -1
  80. data/lib/xlsxrb/style_builder.rb +156 -36
  81. data/lib/xlsxrb/version.rb +3 -1
  82. data/lib/xlsxrb.rb +1510 -231
  83. data/rbs_collection.lock.yaml +224 -0
  84. data/rbs_collection.yaml +19 -0
  85. data/sig/generated/xlsxrb/elements.rbs +8 -0
  86. data/sig/generated/xlsxrb/ooxml.rbs +23 -0
  87. data/sig/generated/xlsxrb/style_builder.rbs +88 -0
  88. data/sig/generated/xlsxrb/version.rbs +5 -0
  89. metadata +67 -29
  90. data/benchmark.rb +0 -399
  91. data/measure_memory.rb +0 -42
  92. data/sig/xlsxrb.rbs +0 -23
data/benchmark.rb DELETED
@@ -1,399 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- ENV["GEM_HOME"] = File.expand_path("tmp/vendor/bundle", __dir__)
4
- ENV["GEM_PATH"] = ENV.fetch("GEM_HOME", nil)
5
-
6
- require "bundler/inline"
7
-
8
- gemfile do
9
- source "https://rubygems.org"
10
- gem "benchmark", "0.5.0"
11
- gem "rexml", "3.4.4"
12
- gem "zlib", "3.2.3"
13
- gem "xlsxtream", "3.1.0"
14
- gem "caxlsx", "4.4.2"
15
- gem "rubyXL", "3.4.35"
16
- gem "fast_excel", "0.5.0"
17
- gem "roo", "3.0.0"
18
- gem "creek", "2.6.3"
19
- gem "csv", "3.3.2"
20
- gem "xsv", "1.4.0"
21
- gem "base64", "0.2.0"
22
- gem "opentelemetry-sdk", "1.11.0"
23
- end
24
-
25
- require "json"
26
- require "benchmark"
27
- require "fileutils"
28
- require "objspace"
29
- require_relative "lib/xlsxrb"
30
-
31
- args = ARGV.dup
32
- KEEP_FILES = args.delete("--keep-files")
33
-
34
- ROWS = (args[0] || 10_000).to_i
35
- COLS = 10
36
- ITERATIONS = 5
37
- READ_TEST_FILE = "tmp/benchmark_read_test.xlsx"
38
-
39
- OUTPUT_FILES = {
40
- "xlsxrb (Streaming)" => "tmp/write_xlsxrb_stream.xlsx",
41
- "xlsxrb (In-Memory)" => "tmp/write_xlsxrb_mem.xlsx",
42
- "caxlsx (In-Memory)" => "tmp/write_caxlsx.xlsx",
43
- "xlsxtream (Streaming)" => "tmp/write_xlsxtream.xlsx",
44
- "fast_excel (Streaming)" => "tmp/write_fast_excel.xlsx",
45
- "rubyXL (In-Memory)" => "tmp/write_rubyXL.xlsx",
46
- "Read source file" => READ_TEST_FILE
47
- }.freeze
48
-
49
- puts "Target: #{ROWS} rows x #{COLS} columns (#{ROWS * COLS} cells)"
50
- puts "Iterations: #{ITERATIONS}"
51
- puts "Keep generated files: #{KEEP_FILES ? "yes" : "no"}"
52
- puts "Preparing test file for read benchmarks..."
53
-
54
- # Prepare test file for read benchmarks
55
- Xlsxrb.generate(READ_TEST_FILE) do |w|
56
- w.add_sheet("Test") do |s|
57
- ROWS.times do |r|
58
- row_data = Array.new(COLS) { |c| (r * COLS) + c }
59
- s.add_row(row_data)
60
- end
61
- end
62
- end
63
-
64
- def run_in_subprocess(_name, &block)
65
- File.write("tmp/bench_task.rb", <<~RUBY)
66
- ENV['BUNDLE_GEMFILE'] = ''
67
- ENV['BUNDLE_IGNORE_CONFIG'] = '1'
68
- ENV['GEM_HOME'] = File.expand_path('tmp/vendor/bundle', __dir__)
69
- ENV['GEM_PATH'] = ENV['GEM_HOME']
70
-
71
- require 'bundler/inline'
72
- gemfile do
73
- source 'https://rubygems.org'
74
- gem 'benchmark', '0.5.0'
75
- gem 'rexml', '3.4.4'
76
- gem 'zlib', '3.2.3'
77
- gem 'xlsxtream', '3.1.0'
78
- gem 'caxlsx', '4.4.2'
79
- gem 'rubyXL', '3.4.35'
80
- gem 'fast_excel', '0.5.0'
81
- gem 'roo', '3.0.0'
82
- gem 'creek', '2.6.3'
83
- gem 'csv', '3.3.2'
84
- gem 'xsv', '1.4.0'
85
- gem 'base64', '0.2.0'
86
- gem 'opentelemetry-sdk', '1.11.0'
87
- end
88
- require 'csv'
89
- require 'base64'
90
- require 'json'
91
- require 'benchmark'
92
- require 'opentelemetry/sdk'
93
- require_relative '../lib/xlsxrb'
94
-
95
- ROWS = #{ROWS}
96
- COLS = 10
97
- READ_TEST_FILE = "tmp/benchmark_read_test.xlsx"
98
-
99
- def get_io_stats
100
- return { rchar: 0, wchar: 0, read_bytes: 0, write_bytes: 0 } unless File.exist?('/proc/self/io')
101
-
102
- stats = {}
103
- File.readlines('/proc/self/io').each do |line|
104
- key, value = line.split(':')
105
- stats[key.strip.to_sym] = value.to_i if key && value
106
- end
107
- stats
108
- end
109
-
110
- class BenchmarkSpanProcessor < OpenTelemetry::SDK::Trace::SpanProcessor
111
- def on_start(span, _parent_context)
112
- return unless span.name == 'benchmark_task'
113
- #{" "}
114
- span.set_attribute('bench.gc.count.start', GC.stat[:count])
115
- span.set_attribute('bench.alloc.objects.start', GC.stat[:total_allocated_objects])
116
- span.set_attribute('bench.time.start', Process.clock_gettime(Process::CLOCK_MONOTONIC))
117
- span.set_attribute('bench.cpu.utime.start', Process.times.utime)
118
- span.set_attribute('bench.cpu.stime.start', Process.times.stime)
119
- @io_start = get_io_stats
120
- #{" "}
121
- @max_mem_mb = 0.0
122
- @watcher = Thread.new do
123
- loop do
124
- mem = `ps -o rss= -p \#{Process.pid}`.to_f / 1024.0
125
- @max_mem_mb = mem if mem > @max_mem_mb
126
- sleep 0.05
127
- end
128
- end
129
- end
130
-
131
- def on_finish(span)
132
- return unless span.name == 'benchmark_task'
133
- #{" "}
134
- @watcher.kill
135
- mem = `ps -o rss= -p \#{Process.pid}`.to_f / 1024.0
136
- @max_mem_mb = mem if mem > @max_mem_mb
137
-
138
- gc_start = span.attributes['bench.gc.count.start']
139
- alloc_start = span.attributes['bench.alloc.objects.start']
140
- time_start = span.attributes['bench.time.start']
141
- utime_start = span.attributes['bench.cpu.utime.start']
142
- stime_start = span.attributes['bench.cpu.stime.start']
143
- io_end = get_io_stats
144
- #{" "}
145
- gc_diff = GC.stat[:count] - gc_start
146
- alloc_diff = GC.stat[:total_allocated_objects] - alloc_start
147
-
148
- written_bytes = io_end[:wchar] - @io_start[:wchar]
149
- read_bytes = io_end[:rchar] - @io_start[:rchar]
150
-
151
- end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
152
- end_times = Process.times
153
-
154
- elapsed = end_time - time_start
155
- cpu_time = (end_times.utime - utime_start) + (end_times.stime - stime_start)
156
- cpu_percent = elapsed > 0 ? (cpu_time / elapsed) * 100 : 0.0
157
-
158
- puts JSON.dump({
159
- time: elapsed,
160
- cpu: cpu_percent,
161
- memory: @max_mem_mb,
162
- gc_count: gc_diff,
163
- alloc_objects: alloc_diff,
164
- rchar: read_bytes,
165
- wchar: written_bytes
166
- })
167
- end
168
- end
169
-
170
- OpenTelemetry::SDK.configure do |c|
171
- c.add_span_processor(BenchmarkSpanProcessor.new)
172
- end
173
-
174
- tracer = OpenTelemetry.tracer_provider.tracer('benchmark')
175
- GC.start
176
-
177
- tracer.in_span('benchmark_task') do
178
- # --- TASK START ---
179
- #{block.call}
180
- # --- TASK END ---
181
- end
182
- RUBY
183
-
184
- output = Bundler.with_unbundled_env do
185
- `ruby tmp/bench_task.rb 2>/dev/null`
186
- end
187
- begin
188
- JSON.parse(output, symbolize_names: true)
189
- rescue StandardError => e
190
- puts "Error: #{e.message} with output: #{output.inspect}"
191
- nil
192
- end
193
- end
194
-
195
- def median(array)
196
- return 0.0 if array.empty?
197
- sorted = array.sort
198
- len = sorted.length
199
- (sorted[(len - 1) / 2] + sorted[len / 2]) / 2.0
200
- end
201
-
202
- def run_benchmark(name, snippet)
203
- print format("%-25s", name)
204
- results = ITERATIONS.times.map do
205
- print "."
206
- run_in_subprocess(name) { snippet }
207
- end
208
- puts
209
-
210
- valid_results = results.compact
211
-
212
- median_time = median(valid_results.map { |r| r[:time] }.compact)
213
- median_cpu = median(valid_results.map { |r| r[:cpu] }.compact)
214
- median_mem = median(valid_results.map { |r| r[:memory] }.compact)
215
- median_gc = median(valid_results.map { |r| r[:gc_count] }.compact)
216
- median_alloc = median(valid_results.map { |r| r[:alloc_objects] }.compact)
217
- median_wchar = median(valid_results.map { |r| r[:wchar] }.compact)
218
- median_rchar = median(valid_results.map { |r| r[:rchar] }.compact)
219
-
220
- {
221
- name: name,
222
- time: median_time,
223
- cpu: median_cpu,
224
- memory: median_mem,
225
- gc_count: median_gc,
226
- alloc_m: median_alloc / 1_000_000.0,
227
- wchar_mb: median_wchar / 1_048_576.0,
228
- rchar_mb: median_rchar / 1_048_576.0
229
- }
230
- end
231
-
232
- def format_row(result)
233
- format("| %-25<name>s | %8.2<time>f s | %9.1<memory>f MB | %8.1<gc_count>f |", result)
234
- end
235
-
236
- puts "\n--- Write Benchmarks ---"
237
- write_results = []
238
-
239
- write_results << run_benchmark("xlsxrb (Streaming)", <<~RUBY
240
- Xlsxrb.generate("tmp/write_xlsxrb_stream.xlsx") do |writer|
241
- writer.add_sheet("Sheet1") do |sheet|
242
- ROWS.times do |r|
243
- row_data = Array.new(COLS) { |c| r * COLS + c }
244
- sheet.add_row(row_data)
245
- end
246
- end
247
- end
248
- RUBY
249
- )
250
-
251
- write_results << run_benchmark("xlsxrb (In-Memory)", <<~RUBY
252
- workbook = Xlsxrb.build do |w|
253
- w.add_sheet("Sheet1") do |sheet|
254
- ROWS.times do |r|
255
- row_data = Array.new(COLS) { |c| r * COLS + c }
256
- sheet.add_row(row_data)
257
- end
258
- end
259
- end
260
- Xlsxrb.write("tmp/write_xlsxrb_mem.xlsx", workbook)
261
- RUBY
262
- )
263
-
264
- write_results << run_benchmark("caxlsx (In-Memory)", <<~RUBY
265
- begin
266
- p = Axlsx::Package.new
267
- sheet = p.workbook.add_worksheet(name: "Sheet1")
268
- ROWS.times do |r|
269
- sheet.add_row(Array.new(COLS) { |c| r * COLS + c })
270
- end
271
- p.serialize("tmp/write_caxlsx.xlsx")
272
- rescue Zlib::BufError => e
273
- File.write("tmp/write_caxlsx.xlsx", "")
274
- end
275
- RUBY
276
- )
277
-
278
- write_results << run_benchmark("xlsxtream (Streaming)", <<~RUBY
279
- begin
280
- Xlsxtream::Workbook.open("tmp/write_xlsxtream.xlsx") do |workbook|
281
- workbook.write_worksheet("Sheet1") do |sheet|
282
- ROWS.times do |r|
283
- sheet << Array.new(COLS) { |c| r * COLS + c }
284
- end
285
- end
286
- end
287
- rescue Zlib::BufError => e
288
- File.write("tmp/write_xlsxtream.xlsx", "")
289
- end
290
- RUBY
291
- )
292
-
293
- write_results << run_benchmark("fast_excel (Streaming)", <<~RUBY
294
- File.delete("tmp/write_fast_excel.xlsx") if File.exist?("tmp/write_fast_excel.xlsx")
295
- workbook = FastExcel.open("tmp/write_fast_excel.xlsx", constant_memory: true)
296
- sheet = workbook.add_worksheet("Sheet1")
297
- ROWS.times do |r|
298
- sheet.append_row(Array.new(COLS) { |c| r * COLS + c })
299
- end
300
- workbook.close
301
- RUBY
302
- )
303
-
304
- write_results << run_benchmark("rubyXL (In-Memory)", <<~RUBY
305
- workbook = RubyXL::Workbook.new
306
- sheet = workbook.worksheets[0]
307
- ROWS.times do |r|
308
- COLS.times do |c|
309
- sheet.add_cell(r, c, r * COLS + c)
310
- end
311
- end
312
- workbook.write("tmp/write_rubyXL.xlsx")
313
- RUBY
314
- )
315
-
316
- puts "\n--- Read Benchmarks ---"
317
- read_results = []
318
-
319
- read_results << run_benchmark("xlsxrb (Streaming)", <<~RUBY
320
- count = 0
321
- Xlsxrb.foreach(READ_TEST_FILE) do |row|
322
- count += row.cells.size
323
- end
324
- RUBY
325
- )
326
-
327
- read_results << run_benchmark("xlsxrb (In-Memory)", <<~RUBY
328
- workbook = Xlsxrb.read(READ_TEST_FILE)
329
- count = 0
330
- workbook.sheets[0].rows.each do |row|
331
- count += row.cells.size
332
- end
333
- RUBY
334
- )
335
-
336
- read_results << run_benchmark("creek (Streaming)", <<~RUBY
337
- creek = Creek::Book.new(READ_TEST_FILE)
338
- sheet = creek.sheets[0]
339
- count = 0
340
- sheet.simple_rows.each do |row|
341
- count += row.size
342
- end
343
- RUBY
344
- )
345
-
346
- read_results << run_benchmark("roo (Streaming)", <<~RUBY
347
- xlsx = Roo::Excelx.new(READ_TEST_FILE)
348
- count = 0
349
- xlsx.each_row_streaming do |row|
350
- count += row.size
351
- end
352
- RUBY
353
- )
354
-
355
- read_results << run_benchmark("rubyXL (In-Memory)", <<~RUBY
356
- workbook = RubyXL::Parser.parse(READ_TEST_FILE)
357
- count = 0
358
- workbook.worksheets[0].each do |row|
359
- count += row.cells.size if row
360
- end
361
- RUBY
362
- )
363
-
364
- read_results << run_benchmark("xsv (Streaming)", <<~RUBY
365
- workbook = Xsv.open(READ_TEST_FILE)
366
- count = 0
367
- workbook[0].each do |row|
368
- count += row.size
369
- end
370
- RUBY
371
- )
372
-
373
- # Print markdown tables
374
- puts "\n\n### Write Performance (#{ROWS * COLS} cells)"
375
- puts "| Library | Time | Peak Memory | GC Count |"
376
- puts "|---------------------------|------------|--------------|----------|"
377
- write_results.sort_by { |r| r[:time] }.each { |r| puts format_row(r) }
378
-
379
- puts "\n### Read Performance (#{ROWS * COLS} cells)"
380
- puts "| Library | Time | Peak Memory | GC Count |"
381
- puts "|---------------------------|------------|--------------|----------|"
382
- read_results.sort_by { |r| r[:time] }.each { |r| puts format_row(r) }
383
-
384
- puts "\n### Generated Files"
385
- puts "| Producer | File path | Status |"
386
- puts "|---------------------------|-------------------------------|----------|"
387
- OUTPUT_FILES.each do |name, path|
388
- status = File.exist?(path) ? "exists" : "missing"
389
- puts format("| %-25<name>s | %-29<path>s | %-8<status>s |", name: name, path: path, status: status)
390
- end
391
-
392
- # Cleanup
393
- if KEEP_FILES
394
- puts "\nKeeping generated files because --keep-files was specified."
395
- else
396
- Dir.glob("tmp/write_*.xlsx").each { |f| FileUtils.rm(f) }
397
- FileUtils.rm(READ_TEST_FILE)
398
- end
399
- FileUtils.rm_f("tmp/bench_task.rb")
data/measure_memory.rb DELETED
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "opentelemetry/sdk"
4
- require "objspace"
5
- require_relative "lib/xlsxrb"
6
-
7
- # Outputs memory and GC stats for a given tracing span
8
- class MemorySpanProcessor < OpenTelemetry::SDK::Trace::SpanProcessor
9
- def on_start(span, _parent_context)
10
- span.set_attribute("ruby.gc.count.start", GC.stat[:count])
11
- span.set_attribute("ruby.memory.bytes_allocated.start", ObjectSpace.memsize_of_all)
12
- end
13
-
14
- def on_finish(span)
15
- gc_start = span.attributes["ruby.gc.count.start"]
16
- mem_start = span.attributes["ruby.memory.bytes_allocated.start"]
17
-
18
- gc_diff = GC.stat[:count] - (gc_start || 0)
19
- mem_diff = ObjectSpace.memsize_of_all - (mem_start || 0)
20
-
21
- mem_mb = mem_diff.to_f / 1024 / 1024
22
-
23
- puts "[#{span.name}] Memory delta: #{mem_mb.round(2)} MB, GC count: #{gc_diff}"
24
- end
25
- end
26
-
27
- OpenTelemetry::SDK.configure do |c|
28
- c.add_span_processor(MemorySpanProcessor.new)
29
- end
30
-
31
- puts "Generating 100,000 cells (10,000 rows x 10 cols) to measure memory..."
32
-
33
- # Using a smaller size first so it runs quickly
34
- Xlsxrb.generate("test_memory.xlsx") do |w|
35
- w.add_sheet("Data") do
36
- 10_000.times do |i|
37
- w.add_row(["A", "B", "C", "D", "E", "F", "G", "H", "I", i])
38
- end
39
- end
40
- end
41
-
42
- puts "Done."
data/sig/xlsxrb.rbs DELETED
@@ -1,23 +0,0 @@
1
- module Xlsxrb
2
- VERSION: String
3
-
4
- module Ooxml
5
- class Event
6
- attr_reader type: Symbol
7
- attr_reader args: Array[untyped]
8
- attr_reader source: Hash[Symbol, untyped]
9
-
10
- def self.new: (type: Symbol, args: Array[untyped], source: Hash[Symbol, untyped]) -> Event
11
- end
12
-
13
- class WorksheetParser
14
- def self.each_event: (String, ?shared_strings: Array[String], ?part_name: String) ?{ (Event) -> void } -> void
15
- | (String, ?shared_strings: Array[String], ?part_name: String) -> Enumerator[Event, void]
16
- end
17
-
18
- class SharedStringsParser
19
- def self.each_event: (String, ?part_name: String) ?{ (Event) -> void } -> void
20
- | (String, ?part_name: String) -> Enumerator[Event, void]
21
- end
22
- end
23
- end