summaryrefslogtreecommitdiffhomepage
path: root/lib/axlsx.rb
diff options
context:
space:
mode:
authorPaul Kmiec <[email protected]>2023-05-13 14:21:21 -0700
committerPaul Kmiec <[email protected]>2023-05-15 13:49:21 -0700
commit4627bcce04ade9c17e1d0c169100a6288195f6ac (patch)
tree7862f4a19e3bca9f6994dca882d5ce92cc3dbf46 /lib/axlsx.rb
parent3b9ac17d8e4dc8b315ac307ffad6f2aa0cb96741 (diff)
downloadcaxlsx-4627bcce04ade9c17e1d0c169100a6288195f6ac.tar.gz
caxlsx-4627bcce04ade9c17e1d0c169100a6288195f6ac.zip
Cache col_ref to avoid allocations
In cases with lots of rows, each column will ask for its col_ref which will always be the same for the same column_index. We can cache this to avoid lots of small string allocations. Modified `CellSerializer` to use `#col_ref` and `#row_ref` avoiding the string allocation caused by `#col_r`
Diffstat (limited to 'lib/axlsx.rb')
-rw-r--r--lib/axlsx.rb30
1 files changed, 22 insertions, 8 deletions
diff --git a/lib/axlsx.rb b/lib/axlsx.rb
index 4f15ba23..6e6a317d 100644
--- a/lib/axlsx.rb
+++ b/lib/axlsx.rb
@@ -112,21 +112,35 @@ module Axlsx
# @note This follows the standard spreadsheet convention of naming columns A to Z, followed by AA to AZ etc.
# @return [String]
def self.col_ref(index)
- chars = +''
- while index >= 26 do
- index, char = index.divmod(26)
- chars.prepend((char + 65).chr)
- index -= 1
+ # Every row will call this for each column / cell and so we can cache result and avoid lots of small object
+ # allocations.
+ @col_ref ||= {}
+ @col_ref[index] ||= begin
+ i = index
+ chars = +''
+ while i >= 26
+ i, char = i.divmod(26)
+ chars.prepend((char + 65).chr)
+ i -= 1
+ end
+ chars.prepend((i + 65).chr)
+ chars.freeze
+ chars
end
- chars.prepend((index + 65).chr)
- chars
+ end
+
+ # converts the row index into string values.
+ # @note The spreadsheet rows are 1-based and the passed in index is 0-based, so we add 1.
+ # @return [String]
+ def self.row_ref(index)
+ (index + 1).to_s
end
# @return [String] The alpha(column)numeric(row) reference for this sell.
# @example Relative Cell Reference
# ws.rows.first.cells.first.r #=> "A1"
def self.cell_r(c_index, r_index)
- col_ref(c_index) << (r_index + 1).to_s
+ col_ref(c_index) + row_ref(r_index)
end
# Creates an array of individual cell references based on an excel reference range.