Skip to content

Commit cf650e2

Browse files
authored
Merge pull request #126 from willtebbutt/wct/accelerate-wrapdims
Make wrapdims more performant
2 parents c21fac1 + a91c7f8 commit cf650e2

File tree

3 files changed

+32
-9
lines changed

3 files changed

+32
-9
lines changed

Project.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "AxisKeys"
22
uuid = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5"
33
license = "MIT"
4-
version = "0.2.7"
4+
version = "0.2.8"
55

66
[deps]
77
AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c"
@@ -23,6 +23,7 @@ BenchmarkTools = "0.5, 1.0"
2323
ChainRulesCore = "1"
2424
ChainRulesTestUtils = "1"
2525
CovarianceEstimation = "0.2"
26+
DataFrames = "1"
2627
FiniteDifferences = "0.12"
2728
IntervalSets = "0.5.1, 0.6, 0.7"
2829
InvertedIndices = "1.0"
@@ -36,6 +37,7 @@ julia = "1.6"
3637
[extras]
3738
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
3839
ChainRulesTestUtils = "cdddcdb0-9152-4a09-a978-84456f9df70a"
40+
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
3941
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
4042
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
4143
FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000"
@@ -45,4 +47,4 @@ UniqueVectors = "2fbcfb34-fd0c-5fbb-b5d7-e826d8f5b0a9"
4547
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
4648

4749
[targets]
48-
test = ["BenchmarkTools", "ChainRulesTestUtils", "Dates", "FiniteDifferences", "FFTW", "NamedArrays", "Test", "UniqueVectors", "Unitful"]
50+
test = ["BenchmarkTools", "ChainRulesTestUtils", "DataFrames", "Dates", "FiniteDifferences", "FFTW", "NamedArrays", "Test", "UniqueVectors", "Unitful"]

src/tables.jl

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,22 +138,30 @@ function populate!(A, table, value::Symbol; force=false)
138138
# Use a BitArray mask to detect duplicates and error instead of overwriting.
139139
mask = force ? falses() : falses(size(A))
140140

141-
for r in Tables.rows(table)
142-
vals = Tuple(Tables.getcolumn(r, c) for c in dimnames(A))
143-
inds = map(findindex, vals, axiskeys(A))
141+
cols = Tables.columns(table)
142+
value_column = Tables.getcolumn(cols, value)
143+
axis_key_columns = Tuple(Tables.getcolumn(cols, c) for c in dimnames(A))
144+
return populate_function_barrier!(A, value_column, axis_key_columns, mask, force)
145+
end
146+
147+
# eltypes of value and axis_key_columns aren't inferable in `populate!` if the `table`
148+
# doesn't have typed columns, as is the case for DataFrames. By passing them into
149+
# `populate_function_barrier!` once they've been pulled out of a DataFrame ensures
150+
# inference is possible for the loop.
151+
function populate_function_barrier!(A, value_column, axis_key_columns, mask, force)
152+
for (val, keys...) in zip(value_column, axis_key_columns...)
153+
inds = map(AxisKeys.findindex, keys, axiskeys(A))
144154

145155
# Handle duplicate error checking if applicable
146156
if !force
147157
# Error if mask already set.
148-
mask[inds...] && throw(ArgumentError("Key $vals is not unique"))
158+
mask[inds...] && throw(ArgumentError("Key $keys is not unique"))
149159
# Set mask, marking that we've set this index
150160
setindex!(mask, true, inds...)
151161
end
152162

153-
# Insert our value into the data array
154-
setindex!(A, Tables.getcolumn(r, value), inds...)
163+
setindex!(A, val, inds...)
155164
end
156-
157165
return A
158166
end
159167

test/_packages.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
using Test, AxisKeys
22

3+
function count_allocs(f, args...)
4+
stats = @timed f(args...)
5+
return Base.gc_alloc_count(stats.gcstats)
6+
end
7+
38
@testset "offset" begin
49
using OffsetArrays
510

@@ -38,6 +43,14 @@ end
3843
@test dimnames(k) == (:aa,)
3944
end
4045
end
46+
@testset "DataFrames" begin
47+
using DataFrames: DataFrame
48+
49+
X = KeyedArray(randn(1000, 1500), a=1:1000, b=1:1500)
50+
df = DataFrame(X)
51+
wrapdims(df, :value, :a, :b) # compile
52+
@test count_allocs(wrapdims, df, :value, :a, :b) < 1_000
53+
end
4154
@testset "tables" begin
4255
using Tables
4356

0 commit comments

Comments
 (0)