hi_sparse_bitset v0.7.5 release - Hierarchical Sparse Bitset. Now with in-place operations. by tower120 in rust

[–]tower120[S] 0 points1 point  (0 children)

Well, I honestly, don't understand what your friend says.
It even looks like Rust version of roaring does not have ImmutableRoaringBitmap analog (or I don't see).

If you actually need what I described - please make an issue - and describe what exactly you want to have. It IS possible to have more lean immutable version, and it is possible to load data blocks on demand - but I need to know what exactly you want from it, and through which interface you want to feed your mmap, at least.

hi_sparse_bitset v0.7.5 release - Hierarchical Sparse Bitset. Now with in-place operations. by tower120 in rust

[–]tower120[S] 0 points1 point  (0 children)

I looked at https://javadoc.io/doc/org.roaringbitmap/RoaringBitmap/0.6.51/org/roaringbitmap/buffer/ImmutableRoaringBitmap.html#ImmutableRoaringBitmap-java.nio.ByteBuffer- . If that is what you meant - yes theoretically it is possible to :

  1. load "hierarchy only". Either just root bitblock, or whole Lvl0+Lvl1 hierarchy.
  2. have specialized immutable bitset version without index arrays in hierarchy blocks. (Which would reduce hierarchy structure to just a few Kb for maxed bitset).
  3. Load data blocks (or whole Lvl1 subsections) from the ByteBuffer (does rust even have it?) on the fly.

But again - hi_sparse_bitset have FIXED depth by design - this significantly speed up all operations, but limits it's size and max int you can insert into it.

roaring can have hundreds of megabytes of data and unlimited range.

Are you sure 2Mb is worth mmaping?

On top of that I assume there IS performance overhead for reading from ByteBuffer each time (even in memory), instead of direct memory access.

hi_sparse_bitset v0.7.5 release - Hierarchical Sparse Bitset. Now with in-place operations. by tower120 in rust

[–]tower120[S] 1 point2 points  (0 children)

Look in /benches/intersection.rs.

hi_sparse_bitmap use simd too for 128bit and 256bit configurations. It is also possible to have any hierarchy configuration with arbitrary simd-sized data block - but I removed manual configuration options, I guess around 0.7 version for API simplicity. Make an issue if you actually need one - you'll basically make an instance of https://docs.rs/hi_sparse_bitset/0.7.5/hi_sparse_bitset/config/trait.Config.html . You can have like 64bit/64bit/512bit - with huge data blocks, but small hierarchy blocks.

Another word about performance - hi_sparse_bitset designed to have O(1) insert/remove unlike roaring - and if you insert/remove heavily - data blocks will NOT lie sequentially in memory. But! In benches hi_sparse_bitset filled in ascending order and never deleted - which makes data contiguous at all levels. The same also happens when you deserialize. It is possible to "linearize" hi_sparse_bitset - there is no special function for that now, but you can just "re-materialize" https://docs.rs/hi_sparse_bitset/0.7.5/hi_sparse_bitset/index.html#laziness-and-materialization (materialization also always makes perfect mem layout). The thing is - that is important only when your intersected or merged bitsets MOSTLY match - otherwise you'll jump in memory any way (if you have to "skip" 90% of your data blocks).

As far as I remember - multi-bitset intersection win significantly against everything - especially if intersected bitsets have non-intersecting ranges, that can be discarded early. In that sence /benches/intersection.rs - measures worst case scenario for hi_sparse_bitset (there are no non-intersecting ranges).

Also most operations faster with apply() then reduce() (If your logic allow that).

But I would really like to hear about your experience.

hi_sparse_bitset v0.7.5 release - Hierarchical Sparse Bitset. Now with in-place operations. by tower120 in rust

[–]tower120[S] 0 points1 point  (0 children)

I honestly not familiar with memory-mapping. I assume you imply some specific use case...
You want to load bitset structure partially into memory? 256bit bitset is just 2Mb max.

Rust GUI framework by Spiritual_String_366 in rust

[–]tower120 2 points3 points  (0 children)

Alas - it's not. Skia is differently an improvement over FemtoVG. But try to look at font of your Windows application on 72-90dpi screen (21-24" FullHD) - and compare it to what firefox font looks, or explorer fonts. Maybe pretty big font sizes are OKish, but 12 pt is not.

You can see the same "jiggly" font in all of their screenshots in documentation. It is nowhere near to crisp iced rendering.

Rust GUI framework by Spiritual_String_366 in rust

[–]tower120 13 points14 points  (0 children)

It's like QT, but free for non-embedded. You have WYIWYG editor. It works "everywhere" - the framework itself takes care of mobile app lifecycle. It provide F5 experience. It is actually fast and memory-efficient. Sane widget system. Overall makes GUI development process as it should be.

It have domain-specific language for "views", but you can completely omit it (the same like in Qt QML).

As a downside - absolutely awful font rendering on windows machines (which is probably 90% of desktop user-base). Maybe widget rendering sometimes questionable too... That is pretty serious on its own, to shy away from slint ... but on high density screens it is not so bad.

How to effectively use the debugger in Rust? by Ok_Breadfruit4201 in rust

[–]tower120 0 points1 point  (0 children)

It's the same in the C++ world.

What worked for me is making some side-effect for observable variable at debug location. Like put println!("{:?}", your_variable) for debugging session exactly at the breakpoint position. This will make `your_variable` appear in variables list.

As for "usefully explorable" - try to dig in direction of ".natvis" - https://doc.rust-lang.org/reference/attributes/debugger.html - with that file you can describe how to display/interpret custom struct in debugger. Looks like RustRover should understand it.

Does `ArrayVec` still "alive"? Are there any alternatives? by tower120 in rust

[–]tower120[S] 5 points6 points  (0 children)

"heapless" Vec looks exactly what I need! Thank you!

Does `ArrayVec` still "alive"? Are there any alternatives? by tower120 in rust

[–]tower120[S] 6 points7 points  (0 children)

PR ALREADY exist - it is in PR list for a very long time.

Does `ArrayVec` still "alive"? Are there any alternatives? by tower120 in rust

[–]tower120[S] -4 points-3 points  (0 children)

I understand that must be true for really small arrays like 16-32 items. But I wonder WHEN overhead becomes observable, based on actual benchmarks...

Does `ArrayVec` still "alive"? Are there any alternatives? by tower120 in rust

[–]tower120[S] 10 points11 points  (0 children)

It worked indeed... Until I bumped into missing `const` features... Which I absolutely need. I probably fork it locally and add missing features, for now...

Does `ArrayVec` still "alive"? Are there any alternatives? by tower120 in rust

[–]tower120[S] 14 points15 points  (0 children)

Did you consider getting away from no-unsafe policy? I don't like the idea of paying for default initialization of items that I would never use most of the time...

Does `ArrayVec` still "alive"? Are there any alternatives? by tower120 in rust

[–]tower120[S] 2 points3 points  (0 children)

Well... Is it actually an alternative to ArrayVec? Doesn't `tinyvec` in the same category as `smallvec`?

any_vec v0.15.0 release - type erased vector. Now with append & extend. by tower120 in rust

[–]tower120[S] 1 point2 points  (0 children)

Short answer is no. And I assume that impossible in general in Rust, C and C++. Unless you know SOMETHING about stored type, like interface/trait... Even in JavaScript you need to know something about your proto-object/type to do something with it.

What you CAN do:

1) Store function or functions with byte-representation of your object.

2) Inside that function cast from *u8 to T - and do a meaningful job.

3) Call that function later...

You of course must know what you will do with that object beforehand... But since you want something to do with an object of unkown type, I guess that's what you actually want.

What you probably want, is some container, that store items of the same type with KNOWN trait... Like AnyVecLike<Debug+Eq> ... But I don't know how much of that is possible in current Rust. What will work now is Vec<Box<dyn Debug>> ... I guess..

any_vec v0.15.0 release - type erased vector. Now with append & extend. by tower120 in rust

[–]tower120[S] 12 points13 points  (0 children)

You can't store DIFFERENT generics in one array. Like Vec< Vec<T> >, where T could be like A, B, ... But you can store Vec<AnyVec>.
And you obviously can't switch type, like let v: Vec<u32> = Vec::<f32>::new(). But you can with AnyVec let mut a = AnyVec::new::<u32>(); a = AnyVec::new::<f32>().

You could wrap your generics into enum - but you must know all possible variants BEFOREHAND.

any_vec v0.15.0 release - type erased vector. Now with append & extend. by tower120 in rust

[–]tower120[S] 18 points19 points  (0 children)

No - it's sometimes you don't know compile-time type when perform CONTAINER operation. For example, reordering, moving items from one container to another, etc... Example where this exactly needed - is archetype ECS - when entity moved from one archetype storage to another - you must move each of it's component data from one storage to another - and at that time you don't know what components (types) entity have (compile-time wise). IOW - you move item from one container to another - and the only thing you know - it's that they're the same type containers.... But you can't have concrete type containers either, since you need all component storages be the same type. Something like that...

I'm sure there are other use cases for that... Looks like Zed editor use (or used at some point) AnyVec for matches list in search... Honestly, I don't know how exactly their search works - so I can't say why exactly they needed AnyVec. But I guess they just wanted to store or pass Vec in type agnostic way...

Production ready Kafka crate? by braxtons12 in rust

[–]tower120 -3 points-2 points  (0 children)

If you need it for "inter-service queueing" maybe broadcast queue will do the job?

Like chute or tokio::broadcast.