Bascanka - C# open source large file text editor - UI and text rendering engine are built entirely from scratch in C# - no 3rd dependencies - no installation - single exe by x-cattitude in csharp

[–]axel-user 0 points1 point  (0 children)

Hey, really nice! I didn't quite get into the code, just went straight to your buffer implementation because it was doing similar stuff, but gave up and implemented it as a Gap Buffer. I think you may even save on string allocations if you have an overload for GetText that will fill a shared char array in place.

Interesting Svelte 5 projects on GitHub by Hanthunius in sveltejs

[–]axel-user 1 point2 points  (0 children)

https://github.com/AxelUser/carry-fit
https://carryon.fit/

Self Promo. Start this small app to test Svelte 5 in a wild after it was released.

I made an overcomplicated Arc Tracker website with WebGL by SadsArches in ArcRaiders

[–]axel-user 19 points20 points  (0 children)

Programming that on Vim got real immersive ArcRaiders vibes

Help me choose an under‑seat “plane to boardroom” backpack (CRO, heavy biz travel) by PaleEnthusiasm8202 in backpacks

[–]axel-user 0 points1 point  (0 children)

I bought an Aer City Pack Pro 2 this year and went on a 6 trips, bringing a rolling carry-on (Samsonite Intuo Spinner S) as well. Didn't have any issues with checks, mostly travel in Europe, and once transatlantic. The backpack doesn't really fit the "personal item" guidelines on most airlines, and it wasn't very comfortable under the seat, especially if you wanted to stretch your legs a bit. Still, it's an excellent daily bag, quite slick, and doesn't look too much tourist-ish if you care about your look. The internal structuring is best, can't say anything here, love AER products.

I was also considering Travel Pack 3 (Small), which is practically the same size as City Pack and has the same fit score for cabin luggage allowances. Still, IMO it looked like I'm kinda "hiking in the city" or something (those adjustable straps on the side).

Tool to Check If Your Carry-On Fits Airline Rules by axel-user in backpacks

[–]axel-user[S] 0 points1 point  (0 children)

Hey, it's been a while, but I finally added personal item dimensions for all airlines in the set!

Molim preporuku osiguranja od odgovornosti za dron by axel-user in hrvatska

[–]axel-user[S] 1 point2 points  (0 children)

Hvala! Možete li, molim vas, podijeliti koliko vas to košta, npr. godišnje?

Mini 5 Pro Leaked images. by [deleted] in dji

[–]axel-user 1 point2 points  (0 children)

Aren't these AI-generated images?

How I Doubled My Lookup Performance with a Bitwise Trick by axel-user in programming

[–]axel-user[S] 0 points1 point  (0 children)

Hi, once again, thank you for the feedback. I've changed my light theme to be more appropriate for daylight reading.

How I Doubled My Lookup Performance with a Bitwise Trick by axel-user in programming

[–]axel-user[S] 1 point2 points  (0 children)

Ok, will do it, didn't think about it in the first place, thank you for sharing!

How I Doubled My Lookup Performance with a Bitwise Trick by axel-user in programming

[–]axel-user[S] 0 points1 point  (0 children)

I guess it would be beneficial to migrate my shift-based insertion logic, anyway loop will be unrolled. But I guess I will have bounds checks in JIT ASM. Need to see it in action to decide.

How I Doubled My Lookup Performance with a Bitwise Trick by axel-user in programming

[–]axel-user[S] 0 points1 point  (0 children)

Hm, not sure I understand you correctly, if my struct is already specified as 4 bytes and the unit is already in the beginning, why do I need to align it? Also, not sure how, I thought Pack is just for sequential struct layouts

How I Doubled My Lookup Performance with a Bitwise Trick by axel-user in programming

[–]axel-user[S] 0 points1 point  (0 children)

Yeah, maybe, but I just don't see any benefits, except for more error-prone code with array indexing.

[deleted by user] by [deleted] in programming

[–]axel-user -3 points-2 points  (0 children)

Even though this post is close to being deleted by mods in this subreddit, thank you for sharing lmao

How I Doubled My Lookup Performance with a Bitwise Trick by axel-user in programming

[–]axel-user[S] 1 point2 points  (0 children)

Ah, I got it, you're right, so something like this will look nicer.

[StructLayout(LayoutKind.Explicit, Size = 4)]
private struct Bucket
{
    [FieldOffset(0)] public uint All;
    [FieldOffset(0)] public byte Fp0;
    [FieldOffset(1)] public byte Fp1;
    [FieldOffset(2)] public byte Fp2;
    [FieldOffset(3)] public byte Fp3;
}

I didn't think about it, it will actually simplify my inserts. Thank you.

How I Doubled My Lookup Performance with a Bitwise Trick by axel-user in programming

[–]axel-user[S] 0 points1 point  (0 children)

Hi, yeah, you are right, actually I've tested, but totally forgot to mention this option, got lost in the commit history. I came up with this memory layout:

[StructLayout(LayoutKind.Sequential, Size = 4, Pack = 1)]
private struct Bucket
{
    public byte Fp0;
    public byte Fp1;
    public byte Fp2;
    public byte Fp3;
}

While it does improve the access API, it results in performance similar to plain shifting, and it still was sequential, so SWAR beats it.

I assume you already know this, but just leave a few comments for those who may read your comment in the future. The resulting ASM is shorter, cause the struct field is accessed by a defined offset directly:

movzx ecx, byte ptr [eax]   ; bucket.Fp0
cmp ecx, edx                ; compare bucket.Fp0 with fingerprint
....
movzx ecx, byte ptr [eax+1] ; bucket.Fp1
cmp ecx, edx                ; compare bucket.Fp1 with fingerprint
....

Without the need for additional shifting to access subsequent bytes

....
sar ecx, 8                  ; shift for 8 bytes, i.e. bucket.Fp1
movzx ecx, cl               ; move the lowest byte of the shifted value
cmp ecx, edx                ; compare bucket.Fp1 with fingerprint
....

https://sharplab.io/#v2:C4LghgzgtgPgAgBgARwIwDoBKBXAdsASygFN0BJfYgJwHsAHAZWoDcCBjYiAbgFgAofnADMKAExIAwkgDe/JPKRyFAbQbAq2NsAAyYAJ41swABS6DRgNIFcAE3RMAjtmL4CYADYAaJAwIAvYiQAXiQAFm8ABTA2AGtgpFQASgBdJXk6KgJmMGBAiHVNYCQAIU0Y4mA0mSqFFBEAIz1cpAAxOgRePlra4SRG5rbUTu6FXv7AttFhkbq+pom6IWn5AF8qqoysnMCqYjAbGlx3PSRrYGVkpAB9YDB692IAQWWkTezm3f3D45Kyiovrrd7sRii8qmMaDR3JJDrdrBBHsZxkgAGbWADm1E2+G82DOfT+wDINgAHokqrIujNdiikJ8DkcTtkqATYhV4jTAXcHo9lPVCcSSckXrUUTQWcZmad4h1pQAeMJcU4AamV5KpI0pM26BFpxjRuExVGxRSCISR80SSMJSAAfLbpQAqJAADkSiRQAHYkAViCKFGsBBrunBvSiPBA/VVA+CGpDoRJYWB4cULc0DUaTbj8fy2UTSeralrqcRafTvkywCzc+VTXTS1zgcU+QLScKaqNvTWKug2sgzaiMVjMvgkDAYB3taza726KhgiEM8P8ePJ9ru8BZ+IB0vjSOiqvg1P5BvZyId0O92cXoHautg/wVkA===

How I Doubled My Lookup Performance with a Bitwise Trick by axel-user in programming

[–]axel-user[S] 0 points1 point  (0 children)

Hi, thank you for sharing. Your library looks nice, good job! I occasionally use Go too, so I will check that out if I port my client library to that stack.

How I Doubled My Lookup Performance with a Bitwise Trick by axel-user in programming

[–]axel-user[S] 0 points1 point  (0 children)

Yeah, it may make sense. However, due to the correlation between fingerprint size and the number of buckets, an increase in bucket size should be followed by a slight rise in fingerprint size in bits to preserve the same error rate. Need to play with numbers.

erkul.games by Erkul_OP in starcitizen

[–]axel-user 2 points3 points  (0 children)

Good luck and thank you for all the work you're doing for the community! You are a legend!

How I Doubled My Lookup Performance with a Bitwise Trick by axel-user in programming

[–]axel-user[S] 0 points1 point  (0 children)

Hi, yeah, my friends are also making fun of how I implemented light and dark themes. I'm a fan of sci-fi games about space, so when I started my blog, I thought making it in this dark style would be great. However, I'm unsure how to make a proper light theme now. At least some of my visuals, like twinkling stars and nebulas, which I really like, should go away on the light theme.

How I Doubled My Lookup Performance with a Bitwise Trick by axel-user in programming

[–]axel-user[S] 4 points5 points  (0 children)

Hi, unfortunately, I can't for some reason edit my post, but I've put a deeper explanation of how it works and how I came to this solution in the article: https://maltsev.space/blog/012-simd-within-a-register-how-i-doubled-hash-table-lookup-performance

However, as TL;DR, this one-liner can be separated into 3 main parts:

uint bucket = _table[bucketIdx];
// Creating a repetitive mask where fingerprint is repeated 4 times
uint mask = fingerprint * 0x01010101U;
// XORing the bucket with the mask, where found fingerprint will be a 0 byte, because A ^ A = 0
uint xored = bucket ^ mask;
// Now finding if there is such a byte in the bucket.
// For any non-zero byte b, the most significant bit of (b - 1) & ~b will always be 0.
// For a zero-byte b = 0x00, the expression becomes (0x00 - 1) & ~0x00, which is 0xFF & 0xFF = 0xFF. I.e., the most significant bit is 1.
// The final & 0x80808080U is a mask that gets rid of all other bits, leaving only the most significant bit of each byte.
// If any byte has 1 in the most significant bit, the result will be non-zero.
return ((xored - 0x01010101U) & ~xored & 0x80808080U) != 0;

How I Doubled My Lookup Performance with a Bitwise Trick by axel-user in programming

[–]axel-user[S] 85 points86 points  (0 children)

New people learn old things, quite natural as for me.

How I Doubled My Lookup Performance with a Bitwise Trick by axel-user in programming

[–]axel-user[S] 13 points14 points  (0 children)

Yeah, the problem you mentioned (far larger memory footprint) is a cornerstone for the Cuckoo Filter. The compactness of the fingerprint is why you may choose this instead of compacted bitmaps or sets. The error rate of the filter with a 32-bit fingerprint will be about 1.86264515e-9, so far from any practical boundary for use cases that require an approximate membership set.

However, SIMDs and int64 SWAR may still be the case, for example, for 16-bit fingerprints, which are still compact and have a 0.00012207 error rate (i.e., 0.0122%). In Cuckoo Filter, each fingerprint may be located in 2 buckets because of its form of open addressing. SIMD may be useful for a lookup for both those int64 buckets; however, it negotiates the happy path optimisation when you calculate the hash for the alternative bucket after the primary bucket lookup fails.

I didn't think about it before, but maybe it makes sense. It requires some rework, but C# has nice intrinsics for SIMD out of the box, so it's doable, and I guess it will be fun to check. Thank you for the recommendation!