Comments (14)
What code are you using for your benchmark ?
I think this might be related to missing implementation of Iterator::size_hint
and other helper methods in
soa-derive/soa-derive-internal/src/iter.rs
Lines 39 to 51 in bb9d45a
Generally speaking, I am certain there are quite a few performances optimizations that are possible to improve this crate.
from soa-derive.
Please find I just created:
I did 4 fields, if more fields => bigger difference.
https://github.com/inv2004/soa_iter_bench
For me its a bit strange that test_new2 is the fastest and test_new is slow, because prev day I saw that test_new was the fastest and test_new2 x1.5 slower, but faster than test_old.
virtual Intel(R) Atom(TM) CPU C2750 @ 2.40GHz:
running 5 tests
test test_izip ... bench: 517,470 ns/iter (+/- 31,921)
test test_new ... bench: 1,208,318 ns/iter (+/- 38,745)
test test_new2 ... bench: 494,725 ns/iter (+/- 29,403)
test test_old ... bench: 1,203,817 ns/iter (+/- 25,856)
test test_zip ... bench: 509,945 ns/iter (+/- 26,682)
Intel(R) Core(TM) i5-7500 CPU @ 3.40GHz
running 5 tests
test test_izip ... bench: 105,344 ns/iter (+/- 3,834)
test test_new ... bench: 197,468 ns/iter (+/- 6,442)
test test_new2 ... bench: 105,983 ns/iter (+/- 2,385)
test test_old ... bench: 263,211 ns/iter (+/- 6,848)
test test_zip ... bench: 105,318 ns/iter (+/- 2,628)
--added--
not sure that lifetimes are very correct.
from soa-derive.
size_hint did not change anything: inv2004/soa_iter_bench@e594312
running 5 tests
test test_izip ... bench: 106,009 ns/iter (+/- 7,491)
test test_new ... bench: 199,861 ns/iter (+/- 13,772)
test test_new2 ... bench: 106,520 ns/iter (+/- 5,779)
test test_old ... bench: 269,461 ns/iter (+/- 16,255)
test test_zip ... bench: 105,314 ns/iter (+/- 4,614)
from soa-derive.
Oh, OK, I think I understand the issue better! The main problem here might be that we have to create new SRef<'a> at each step of the iteration, and then dereference it.
You should be able to use the soa_zip!
macro instead of izip!
and get at least the same performance (both macro expand to basically the same code)
from soa-derive.
I am not so sure that the problem is in creation of the SRef, because test_izip and test test_zip creates SRef too: https://github.com/inv2004/soa_iter_bench/blob/14803a468f0a153170431d7aa7b62176aa89693d/src/main.rs#L227
new bench without creation of the SRef:
test test_zip ... bench: 523,696 ns/iter (+/- 16,403)
test test_zip_without_ref ... bench: 542,164 ns/iter (+/- 58,219)
from soa-derive.
What does this gives with soa_zip!
?
from soa-derive.
No. I did not use soa_zip! because its not to impl SRef in the case and not possible to make universal solution.
from soa-derive.
Please find update.
I created new test_old2 from test_old and used construction from core::iter::Zip source code: https://github.com/inv2004/soa_iter_bench/blob/d7a30016fcee702331d05ad24a17addb43b806e7/src/main.rs#L101
and now it looks like it improved situation a lot:
running 10 tests
test test_new2_rev_test ... ignored
test test_izip ... bench: 550,991 ns/iter (+/- 34,369)
test test_new ... bench: 1,242,180 ns/iter (+/- 31,991)
test test_new2 ... bench: 628,175 ns/iter (+/- 27,861)
test test_new2_rev ... bench: 702,763 ns/iter (+/- 29,718)
test test_old ... bench: 1,247,024 ns/iter (+/- 20,131)
**test test_old2 ... bench: 622,488 ns/iter (+/- 18,691)**
test test_zip ... bench: 549,055 ns/iter (+/- 26,092)
test test_zip_rev ... bench: 570,239 ns/iter (+/- 27,660)
test test_zip_without_ref ... bench: 554,853 ns/iter (+/- 57,848)
--added--
a bit faster:
fn next(&mut self) -> Option<Self::Item> {
self.a.next().and_then(|a|
Some(SRef{
a,
b:self.b.next().unwrap(),
c:self.c.next().unwrap(),
d:self.d.next().unwrap()})
)
}
I do not know why. Looks like Rust can optimize some loops but cannot others.
from soa-derive.
Wow, this looks good! And should not be too hard to implement also.
Just to know, it sound like you want to abstract over Slice/Vec in your use case, why?
One possibility to do so would be to have an AsSlice
trait that convert everything to a slice, and then work from here. Both XXXVec and XXXSliceMut have a slice()
method that can be used for this.
from soa-derive.
If You would like to implement it, please do not forget about std::iter::DoubleEndedIterator, which is useful for many cases.
I have a different structs, for example S1, S2, S3, S3 with different fields, all of them derive SoA. because vectorized structure calculations are much master + structure of the data is more contant: vec of numbers is easier to use than vectors of structs with numbers.
then I implemented fn calc (for ref) to make some comp with S1,2,3,4 and different fields. Now, with Iterators I can easy write universal function without working with fields:
let sl = (S1Slice or SVec):: new(...);
for x in &sl { x.calc() } .
Unfortunately test_old2 is still ~12% slower than test_zip.
from soa-derive.
I feel like I am a bit annoying, but please find new update:
running 10 tests
test test_new2_rev_test ... ignored
test test_izip ... bench: 505,946 ns/iter (+/- 9,750)
**test test_new ... bench: 501,313 ns/iter (+/- 38,063)**
test test_new2 ... bench: 589,285 ns/iter (+/- 45,108)
test test_new2_rev ... bench: 653,283 ns/iter (+/- 19,451)
test test_old ... bench: 1,197,755 ns/iter (+/- 13,299)
test test_old2 ... bench: 570,729 ns/iter (+/- 36,173)
test test_zip ... bench: 504,843 ns/iter (+/- 31,671)
test test_zip_rev ... bench: 533,405 ns/iter (+/- 43,096)
test test_zip_without_ref ... bench: 509,646 ns/iter (+/- 35,153)
test_new (which uses Zip internally) time is exactly like test_zip. I suppose iter::Zip makes some optimizations, that is why it is the fastest.
Unfortunately this PR will not be so easy like test_old2. But I think that the main problem is to create "pub struct Iter<Zip<Zip<Zip<....>" type and (((a,b),c),d) tuple string.
from soa-derive.
Thank you very much for your investigation here!
from soa-derive.
Thanks to You.
from soa-derive.
Please do not publish, because looks like DoubleEndedIterator and .rev() have performance problems. Do not know why at the moment.
from soa-derive.
Related Issues (20)
- Allow explicit name generation HOT 1
- Use one length and capacity variable for whole struct HOT 23
- Update versions of `syn` and `quote` HOT 3
- Provide FromIterator implementation HOT 3
- Use trait to link the origin struct to generated soa struct HOT 3
- Add access methods HOT 3
- Allow to nest structs of arrays HOT 9
- Nitpick: doc for generated vec-like methods have extra spaces HOT 1
- Does not support generics. HOT 6
- #[soa_attr] on field
- #[serde(skip)] cause struct of array containing different length of field HOT 4
- Const array SoA variant HOT 2
- Cannot find trait `SoAIter` in crate `soa_derive` HOT 3
- Sorting methods for Slice variant HOT 2
- Derive std::iter::Extend HOT 1
- Is it possible to avoid duplicate capacity and size fields? HOT 1
- How do you go from `MyTypeRef` to `MyType` ? HOT 6
- How to set #[pyclass] attribute for soa-derived struct? HOT 2
- cannot move out of type `CheeseVec`, which implements the `Drop` trait HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from soa-derive.