Skip to content

feat: support primitive types in define_property!#915

Draft
k88hudson-cfa wants to merge 2 commits into
mainfrom
k88-generated-newtypes
Draft

feat: support primitive types in define_property!#915
k88hudson-cfa wants to merge 2 commits into
mainfrom
k88-generated-newtypes

Conversation

@k88hudson-cfa
Copy link
Copy Markdown
Collaborator

@k88hudson-cfa k88hudson-cfa commented May 20, 2026

This is a proposal for a possible alternative that supports primitive values. The overall idea is that get_property returns the inner primitive, but you can still use the wrapper type for set_property/with!

let a: u8 = ctx.get_property::<Person, MyAge>(p);
ctx.set_property(p, MyAge(25));
ctx.add_entity(with!(Person, MyAge(25)));

define_property! / define_derived_property!: new primitive form

Before (legacy form, still works)

define_property!(struct Age(u8), Person);
define_property!(struct Score(i32), Person, default_const = Score(0));
define_derived_property!(struct IsAdult(bool), Person, [Age], \|age\| IsAdult(age.0 >= 18));`

After

define_property!(Age: u8, Person);
define_property!(Score: i32, Person, default_const = 0);`
define_derived_property!(IsAdult: bool, Person, [Age], \|age\| IsAdult(age >= 18));

Note: the macro generates pub struct Age(pub u8) plus From<u8>/From<Age> impls

Property trait — new associated type + methods

Before:

pub trait Property<E: Entity>: AnyProperty {
    type CanonicalValue;
    // ...
}

After:

pub trait Property<E: Entity>: AnyProperty {
    type Value: AnyProperty;
    fn into_value(self) -> Self::Value;
    fn from_value(value: Self::Value) -> Self;
    type CanonicalValue;
    // ...
}

@github-actions
Copy link
Copy Markdown

Benchmark Results

Hyperfine

Command Mean [ms] Min [ms] Max [ms] Relative
large_sir::baseline 2.6 ± 0.0 2.5 2.8 1.00 ± 0.03
large_sir::baseline_households 2.6 ± 0.0 2.5 2.8 1.00
large_sir::entities 5.2 ± 0.2 5.1 6.8 2.00 ± 0.10
large_sir::households 5.0 ± 0.1 4.9 5.2 1.91 ± 0.04

Criterion

Regressions (slower)
Group Bench Param Change CI Lower CI Upper
sample_entity sample_entity_single_property_unindexed 10000 24.531% 22.536% 26.588%
sample_entity sample_entity_single_property_unindexed 1000 14.089% 10.962% 17.197%
sample_entity sample_entity_single_property_indexed 1000 10.047% 8.945% 11.157%
sample_entity sample_entity_multi_property_indexed 100000 6.641% 6.092% 7.153%
examples example-basic-infection 6.342% 5.115% 7.784%
sample_entity sample_entity_multi_property_indexed 10000 5.206% 4.861% 5.601%
sample_entity sample_entity_multi_property_indexed 1000 4.758% 4.142% 5.343%
indexing query_people_multiple_individually_indexed_properties_entities 4.646% 4.254% 5.008%
sample_entity sample_entity_single_property_indexed 100000 4.202% 3.376% 5.036%
counts index_after_adding_entities 2.573% 2.404% 2.734%
indexing query_people_count_multiple_individually_indexed_properties_enti 2.205% 1.783% 2.633%
sampling count_and_sampling_single_unindexed_concrete_plus_derived_entiti 2.024% 1.862% 2.198%
Improvements (faster)
Group Bench Param Change CI Lower CI Upper
counts multi_property_unindexed_entities -16.432% -17.599% -15.086%
large_dataset bench_filter_unindexed_entity -14.714% -17.607% -11.683%
large_dataset bench_query_population_indexed_property_entities -13.172% -13.395% -12.963%
sample_entity sample_entity_whole_population 100000 -11.157% -11.814% -10.506%
sample_entity sample_entity_whole_population 1000 -9.462% -10.221% -8.724%
indexing query_people_single_indexed_property_entities -8.225% -8.351% -8.092%
sample_entity sample_entity_whole_population 10000 -6.148% -7.003% -5.269%
indexing query_people_indexed_multi-property_entities -5.685% -6.464% -4.932%
indexing with_query_results_single_indexed_property_entities -4.885% -5.464% -4.501%
sampling sampling_single_known_length_entities -4.592% -4.925% -4.260%
sampling sampling_single_unindexed_entities -4.560% -5.190% -3.773%
sampling sampling_multiple_unindexed_entities -4.267% -4.557% -4.012%
counts single_property_indexed_entities -2.640% -3.149% -2.157%
large_dataset bench_match_entity -2.321% -3.025% -1.643%
indexing with_query_results_multiple_individually_indexed_properties_enti -2.196% -2.898% -1.721%
sampling sampling_multiple_l_reservoir_entities -2.174% -2.411% -1.971%
sampling count_and_sampling_single_known_length_entities -2.112% -2.772% -1.427%
counts multi_property_indexed_entities -1.927% -2.622% -1.075%
indexing query_people_count_single_indexed_property_entities -1.909% -2.200% -1.609%
counts reindex_after_adding_more_entities -1.619% -1.857% -1.413%
Unchanged / inconclusive (CI crosses 0%)
Group Bench Param Change CI Lower CI Upper
large_dataset bench_filter_indexed_entity -2.901% -11.299% 5.848%
sample_entity sample_entity_single_property_indexed 10000 1.458% 0.720% 2.117%
large_dataset bench_query_population_multi_indexed_entities 1.414% 0.893% 1.897%
sampling sampling_multiple_known_length_entities 0.970% 0.433% 1.531%
examples example-births-deaths -0.869% -1.242% -0.513%
indexing query_people_count_indexed_multi-property_entities 0.678% 0.407% 0.944%
algorithm_benches algorithm_sampling_multiple_known_length -0.429% -0.879% -0.066%
large_dataset bench_query_population_derived_property_entities -0.421% -1.097% 0.307%
algorithm_benches algorithm_sampling_single_rand_reservoir -0.402% -0.789% -0.091%
indexing with_query_results_indexed_multi-property_entities 0.380% 0.056% 0.701%
sampling sampling_single_l_reservoir_entities -0.338% -1.332% 0.815%
large_dataset bench_query_population_property_entities -0.317% -0.806% 0.333%
sampling sampling_single_unindexed_concrete_plus_derived_entities -0.243% -0.418% -0.079%
large_dataset bench_query_population_multi_unindexed_entities -0.240% -0.827% 0.480%
algorithm_benches algorithm_sampling_single_l_reservoir -0.240% -0.590% 0.057%
counts concrete_plus_derived_unindexed_entities -0.183% -0.581% 0.272%
counts single_property_unindexed_entities 0.082% -0.205% 0.430%
algorithm_benches algorithm_sampling_multiple_l_reservoir -0.042% -0.400% 0.360%
sample_entity sample_entity_single_property_unindexed 100000 -0.022% -0.251% 0.208%
algorithm_benches algorithm_sampling_single_known_length 0.013% -0.301% 0.448%
Not Compared (no baseline yet)
Group Bench Reason
(none)

github-actions Bot added a commit that referenced this pull request May 20, 2026
@k88hudson-cfa k88hudson-cfa force-pushed the k88-generated-newtypes branch from e37d457 to 1f181fe Compare May 20, 2026 23:50
@github-actions
Copy link
Copy Markdown

Benchmark Results

Hyperfine

Command Mean [ms] Min [ms] Max [ms] Relative
large_sir::baseline 2.7 ± 0.0 2.6 2.8 1.00
large_sir::baseline_households 2.7 ± 0.1 2.6 3.1 1.01 ± 0.03
large_sir::entities 6.1 ± 0.1 5.8 6.3 2.27 ± 0.06
large_sir::households 5.9 ± 0.1 5.7 6.4 2.21 ± 0.06

Criterion

Regressions (slower)
Group Bench Param Change CI Lower CI Upper
sampling count_and_sampling_single_known_length_entities 69.890% 65.688% 73.784%
sample_entity sample_entity_single_property_indexed 10000 14.981% 13.694% 16.284%
sample_entity sample_entity_single_property_unindexed 1000 14.417% 11.593% 17.033%
sample_entity sample_entity_single_property_indexed 100000 11.454% 10.678% 12.173%
large_dataset bench_match_entity 9.682% 9.412% 9.908%
sample_entity sample_entity_single_property_indexed 1000 8.011% 7.188% 8.704%
sample_entity sample_entity_multi_property_indexed 1000 4.811% 4.327% 5.322%
sample_entity sample_entity_multi_property_indexed 10000 4.390% 3.967% 4.746%
sampling sampling_single_unindexed_entities 4.310% 4.087% 4.497%
sample_entity sample_entity_multi_property_indexed 100000 3.692% 3.344% 4.050%
sample_entity sample_entity_whole_population 100000 3.378% 1.340% 5.491%
sample_entity sample_entity_whole_population 1000 3.106% 1.181% 5.132%
large_dataset bench_query_population_indexed_property_entities 2.558% 2.317% 2.798%
counts reindex_after_adding_more_entities 2.033% 1.574% 2.467%
counts index_after_adding_entities 1.304% 1.108% 1.500%
Improvements (faster)
Group Bench Param Change CI Lower CI Upper
sampling sampling_single_unindexed_concrete_plus_derived_entities -35.417% -35.488% -35.338%
sampling count_and_sampling_single_unindexed_concrete_plus_derived_entiti -27.019% -28.338% -25.484%
sampling sampling_single_known_length_entities -22.513% -22.938% -22.008%
large_dataset bench_filter_unindexed_entity -13.327% -16.371% -10.261%
indexing query_people_count_single_indexed_property_entities -11.684% -12.738% -10.639%
algorithm_benches algorithm_sampling_single_known_length -9.038% -13.953% -3.828%
indexing with_query_results_single_indexed_property_entities -7.823% -8.998% -6.510%
counts single_property_indexed_entities -5.578% -7.956% -3.314%
sampling sampling_single_l_reservoir_entities -5.317% -6.564% -4.318%
sampling sampling_multiple_l_reservoir_entities -3.235% -3.740% -2.600%
indexing query_people_count_multiple_individually_indexed_properties_enti -2.295% -2.979% -1.821%
sampling sampling_multiple_unindexed_entities -2.060% -2.183% -1.846%
large_dataset bench_query_population_multi_unindexed_entities -2.042% -2.467% -1.570%
examples example-basic-infection -1.996% -2.530% -1.529%
Unchanged / inconclusive (CI crosses 0%)
Group Bench Param Change CI Lower CI Upper
large_dataset bench_filter_indexed_entity 2.474% -6.039% 11.652%
indexing query_people_multiple_individually_indexed_properties_entities -1.473% -1.793% -0.962%
indexing with_query_results_multiple_individually_indexed_properties_enti -1.463% -2.167% -0.738%
sample_entity sample_entity_whole_population 10000 1.360% -0.526% 3.328%
indexing query_people_indexed_multi-property_entities -1.264% -1.708% -0.912%
indexing with_query_results_indexed_multi-property_entities 1.072% 0.698% 1.365%
sampling sampling_multiple_known_length_entities -0.976% -1.653% -0.239%
examples example-births-deaths 0.879% 0.686% 1.070%
large_dataset bench_query_population_derived_property_entities -0.663% -1.408% 0.050%
algorithm_benches algorithm_sampling_multiple_l_reservoir 0.548% 0.180% 0.890%
large_dataset bench_query_population_multi_indexed_entities 0.494% 0.136% 0.819%
sample_entity sample_entity_single_property_unindexed 10000 -0.398% -1.716% 0.736%
counts multi_property_indexed_entities 0.320% -0.132% 0.743%
counts multi_property_unindexed_entities -0.320% -0.700% -0.041%
algorithm_benches algorithm_sampling_single_rand_reservoir -0.228% -0.650% 0.212%
sample_entity sample_entity_single_property_unindexed 100000 0.201% -0.256% 0.855%
large_dataset bench_query_population_property_entities -0.193% -0.879% 0.416%
algorithm_benches algorithm_sampling_single_l_reservoir -0.163% -0.502% 0.162%
algorithm_benches algorithm_sampling_multiple_known_length 0.143% -0.544% 0.980%
counts single_property_unindexed_entities 0.096% -0.358% 0.747%
indexing query_people_count_indexed_multi-property_entities -0.057% -0.214% 0.100%
indexing query_people_single_indexed_property_entities 0.014% -0.108% 0.151%
counts concrete_plus_derived_unindexed_entities -0.010% -0.245% 0.294%
Not Compared (no baseline yet)
Group Bench Reason
(none)

github-actions Bot added a commit that referenced this pull request May 20, 2026
@k88hudson-cfa
Copy link
Copy Markdown
Collaborator Author

k88hudson-cfa commented May 21, 2026

Here's an overview of all the options I can think of:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants