xlsxrb 0.1.4 → 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 +1 -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 +22 -2
  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 +71 -5
  90. data/benchmark.rb +0 -400
  91. data/measure_memory.rb +0 -42
  92. data/sig/xlsxrb.rbs +0 -23
data/benchmark.rb DELETED
@@ -1,400 +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
-
198
- sorted = array.sort
199
- len = sorted.length
200
- (sorted[(len - 1) / 2] + sorted[len / 2]) / 2.0
201
- end
202
-
203
- def run_benchmark(name, snippet)
204
- print format("%-25s", name)
205
- results = ITERATIONS.times.map do
206
- print "."
207
- run_in_subprocess(name) { snippet }
208
- end
209
- puts
210
-
211
- valid_results = results.compact
212
-
213
- median_time = median(valid_results.map { |r| r[:time] }.compact)
214
- median_cpu = median(valid_results.map { |r| r[:cpu] }.compact)
215
- median_mem = median(valid_results.map { |r| r[:memory] }.compact)
216
- median_gc = median(valid_results.map { |r| r[:gc_count] }.compact)
217
- median_alloc = median(valid_results.map { |r| r[:alloc_objects] }.compact)
218
- median_wchar = median(valid_results.map { |r| r[:wchar] }.compact)
219
- median_rchar = median(valid_results.map { |r| r[:rchar] }.compact)
220
-
221
- {
222
- name: name,
223
- time: median_time,
224
- cpu: median_cpu,
225
- memory: median_mem,
226
- gc_count: median_gc,
227
- alloc_m: median_alloc / 1_000_000.0,
228
- wchar_mb: median_wchar / 1_048_576.0,
229
- rchar_mb: median_rchar / 1_048_576.0
230
- }
231
- end
232
-
233
- def format_row(result)
234
- format("| %-25<name>s | %8.2<time>f s | %9.1<memory>f MB | %8.1<gc_count>f |", result)
235
- end
236
-
237
- puts "\n--- Write Benchmarks ---"
238
- write_results = []
239
-
240
- write_results << run_benchmark("xlsxrb (Streaming)", <<~RUBY
241
- Xlsxrb.generate("tmp/write_xlsxrb_stream.xlsx") do |writer|
242
- writer.add_sheet("Sheet1") do |sheet|
243
- ROWS.times do |r|
244
- row_data = Array.new(COLS) { |c| r * COLS + c }
245
- sheet.add_row(row_data)
246
- end
247
- end
248
- end
249
- RUBY
250
- )
251
-
252
- write_results << run_benchmark("xlsxrb (In-Memory)", <<~RUBY
253
- workbook = Xlsxrb.build do |w|
254
- w.add_sheet("Sheet1") do |sheet|
255
- ROWS.times do |r|
256
- row_data = Array.new(COLS) { |c| r * COLS + c }
257
- sheet.add_row(row_data)
258
- end
259
- end
260
- end
261
- Xlsxrb.write("tmp/write_xlsxrb_mem.xlsx", workbook)
262
- RUBY
263
- )
264
-
265
- write_results << run_benchmark("caxlsx (In-Memory)", <<~RUBY
266
- begin
267
- p = Axlsx::Package.new
268
- sheet = p.workbook.add_worksheet(name: "Sheet1")
269
- ROWS.times do |r|
270
- sheet.add_row(Array.new(COLS) { |c| r * COLS + c })
271
- end
272
- p.serialize("tmp/write_caxlsx.xlsx")
273
- rescue Zlib::BufError => e
274
- File.write("tmp/write_caxlsx.xlsx", "")
275
- end
276
- RUBY
277
- )
278
-
279
- write_results << run_benchmark("xlsxtream (Streaming)", <<~RUBY
280
- begin
281
- Xlsxtream::Workbook.open("tmp/write_xlsxtream.xlsx") do |workbook|
282
- workbook.write_worksheet("Sheet1") do |sheet|
283
- ROWS.times do |r|
284
- sheet << Array.new(COLS) { |c| r * COLS + c }
285
- end
286
- end
287
- end
288
- rescue Zlib::BufError => e
289
- File.write("tmp/write_xlsxtream.xlsx", "")
290
- end
291
- RUBY
292
- )
293
-
294
- write_results << run_benchmark("fast_excel (Streaming)", <<~RUBY
295
- File.delete("tmp/write_fast_excel.xlsx") if File.exist?("tmp/write_fast_excel.xlsx")
296
- workbook = FastExcel.open("tmp/write_fast_excel.xlsx", constant_memory: true)
297
- sheet = workbook.add_worksheet("Sheet1")
298
- ROWS.times do |r|
299
- sheet.append_row(Array.new(COLS) { |c| r * COLS + c })
300
- end
301
- workbook.close
302
- RUBY
303
- )
304
-
305
- write_results << run_benchmark("rubyXL (In-Memory)", <<~RUBY
306
- workbook = RubyXL::Workbook.new
307
- sheet = workbook.worksheets[0]
308
- ROWS.times do |r|
309
- COLS.times do |c|
310
- sheet.add_cell(r, c, r * COLS + c)
311
- end
312
- end
313
- workbook.write("tmp/write_rubyXL.xlsx")
314
- RUBY
315
- )
316
-
317
- puts "\n--- Read Benchmarks ---"
318
- read_results = []
319
-
320
- read_results << run_benchmark("xlsxrb (Streaming)", <<~RUBY
321
- count = 0
322
- Xlsxrb.foreach(READ_TEST_FILE) do |row|
323
- count += row.cells.size
324
- end
325
- RUBY
326
- )
327
-
328
- read_results << run_benchmark("xlsxrb (In-Memory)", <<~RUBY
329
- workbook = Xlsxrb.read(READ_TEST_FILE)
330
- count = 0
331
- workbook.sheets[0].rows.each do |row|
332
- count += row.cells.size
333
- end
334
- RUBY
335
- )
336
-
337
- read_results << run_benchmark("creek (Streaming)", <<~RUBY
338
- creek = Creek::Book.new(READ_TEST_FILE)
339
- sheet = creek.sheets[0]
340
- count = 0
341
- sheet.simple_rows.each do |row|
342
- count += row.size
343
- end
344
- RUBY
345
- )
346
-
347
- read_results << run_benchmark("roo (Streaming)", <<~RUBY
348
- xlsx = Roo::Excelx.new(READ_TEST_FILE)
349
- count = 0
350
- xlsx.each_row_streaming do |row|
351
- count += row.size
352
- end
353
- RUBY
354
- )
355
-
356
- read_results << run_benchmark("rubyXL (In-Memory)", <<~RUBY
357
- workbook = RubyXL::Parser.parse(READ_TEST_FILE)
358
- count = 0
359
- workbook.worksheets[0].each do |row|
360
- count += row.cells.size if row
361
- end
362
- RUBY
363
- )
364
-
365
- read_results << run_benchmark("xsv (Streaming)", <<~RUBY
366
- workbook = Xsv.open(READ_TEST_FILE)
367
- count = 0
368
- workbook[0].each do |row|
369
- count += row.size
370
- end
371
- RUBY
372
- )
373
-
374
- # Print markdown tables
375
- puts "\n\n### Write Performance (#{ROWS * COLS} cells)"
376
- puts "| Library | Time | Peak Memory | GC Count |"
377
- puts "|---------------------------|------------|--------------|----------|"
378
- write_results.sort_by { |r| r[:time] }.each { |r| puts format_row(r) }
379
-
380
- puts "\n### Read Performance (#{ROWS * COLS} cells)"
381
- puts "| Library | Time | Peak Memory | GC Count |"
382
- puts "|---------------------------|------------|--------------|----------|"
383
- read_results.sort_by { |r| r[:time] }.each { |r| puts format_row(r) }
384
-
385
- puts "\n### Generated Files"
386
- puts "| Producer | File path | Status |"
387
- puts "|---------------------------|-------------------------------|----------|"
388
- OUTPUT_FILES.each do |name, path|
389
- status = File.exist?(path) ? "exists" : "missing"
390
- puts format("| %-25<name>s | %-29<path>s | %-8<status>s |", name: name, path: path, status: status)
391
- end
392
-
393
- # Cleanup
394
- if KEEP_FILES
395
- puts "\nKeeping generated files because --keep-files was specified."
396
- else
397
- Dir.glob("tmp/write_*.xlsx").each { |f| FileUtils.rm(f) }
398
- FileUtils.rm(READ_TEST_FILE)
399
- end
400
- 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