Home
Blog
Recent Posts 3
Updated
Dot Net Perls

Favorite Python Language Feature

There are so many nice things about the Python language—it has a robust standard library, clear syntax, many libraries, and wide support—that I had to think for a while before writing this post.

Probably my favorite feature from Python is its syntax. The language use indentation to represent nested blocks instead of curly brackets, and it avoids semicolons to end lines. It looks simpler and cleaner than most other languages.

The syntax of Python probably has widespread effects:

It leads to Python's use as a "glue" language, where developers publish libraries that are written in other languages, but used in Python.
It is less intimidating to beginners, which helps the language grow over time.
It is probably more difficult to optimize because of lack of type hints.

In a sense Python's syntax makes it what it is—if it had more complex, expressive syntax, it would have been passed over as a "glue" language and would not have the same library support it has. Beginners would avoid such a language, making it less prevalent. And, like C++ or Rust, if Python had more complex syntax, it could probably be optimized to run faster.

DDoS Attack Mitigated

I have mitigated a DDoS attack on this site that was causing a huge increase in bandwidth use over the last 13 days. I was worried I would go over the bandwidth limits in place on my server, which could be expensive.

The solution was to ban 3 ranges of IPs (with firewalld) that the attackers were using. The requests were obviously malicious and seemed to be aimed at crashing the server somehow. Caddy (my web server) did not crash, although it wasted a lot of CPU time servicing all these requests.

Here is what I found when I enabled logging in Caddy:

The malicious DDoS requests were from (as mentioned) 3 IP ranges only.
Many of the other requests were from web crawling bots and AI bots (some of which I thought I had banned in my robots.txt).
There were some regular human requests still, even on the weekend.

So the Internet has not been entirely consumed by DDoS attacks and AI companies using web crawling bots, but seems to be most of the way there.

Favorite Go Language Feature

The Go programming language has many uncommon features, like fast compile-times, multithreaded routines, and types that are safe to use on threads. But one of the first a new developer will encounter is multiple return values.

It makes sense to me that a method can return multiple values. I mean, it is 2025—we should not be limited to returning one value at a time. Other languages can return tuples, Options, Results, arrays or maps but Go has native support for multiple values.

There are some implications to Go's native multiple value support:

You can assign to the return values with names.
Many functions return an "ok" value as the second value, like the map, which is easy to understand.
You don't need to include any namespaces or modules just for a return type.

It's probably one of the earliest features a new Go developer will encounter, and it is so deeply-built into the language that multiple return values are one of the best features of Go.

Best C# Optimization

C# is a relatively well-performing language—it is compiled and uses a type system that enables many optimizations. But sometimes good performance is not enough—the C# program needs to be as fast as possible. Probably the best C# optimization is to reduce or eliminate allocations.

In C#, every string is allocated upon the managed heap, a section of memory that allows variable-length data to be stored. By removing allocations of strings, we can save accesses to the managed heap, and also the later garbage collection passes that clean up the heap.

There are some other types that benefit from reducing allocations:

Arrays are allocated on the managed heap, so if we reduce the creation of arrays, this will help.
Types like StringBuilder are also placed on the heap, so we should reuse a single StringBuilder instead of creating many of them.
Any class instances, like strings, are also heap-allocated and can cause garbage collection pauses.

Keeping a cache of some sort and reusing these objects instead of allocating new ones has been, in my experience, the most effective C# optimization. You can see some examples on the array and Dictionary C# articles.

Future of This Site

A lot of things have changed over the years I have been updating Dot Net Perls. These days, the Internet is almost a completely different place. I have been thinking about how I want to keep this site updated in the future.

I have encountered many issues recently with this website:

It is time-consuming to maintain due to the number of articles.
Less traffic is being served due to the search engines pushing LLM responses above real, human-written web sites.
Some of the content may become outdated as best practices (and languages themselves) change.

I believe the articles on this site still have value. I will keep maintaining them, but focus more on new writing. I am not sure if this blog is the path forward, but it will be tied to the existing code articles and maintained alongside them.

Zooming Images

Today I made a change to Dot Net Perls that I have been wanting to make for a long time. The site has hundreds of images that I added to make the articles more understandable. The images give color and some interest to the pages.

However, some users of the site probably don't find them useful. So my solution is to add a "click to expand" feature on the images—give them a thumbnail and then if someone is interested, the person can click on it.

I implemented this with CSS and HTML only—it uses a check-box input element, and the "checked" selector in CSS. It is kind of cool I think (maybe I am easily impressed though). I hope you find the zooming images feature helpful.

Favorite Rust Optimization

I have spent quite a bit of time writing Rust code, and also optimizing that same Rust code. In fact I have doubtless spent more time optimizing code than the time saved by the optimizations. In any case, I have some favorite optimizations.

The programs I use tend to copy data (byte vectors) from one source to another. They process data byte-by-byte. But the optimization is to append ranges of bytes, with extend_from_slice, instead of using push to append each byte individually.

This has some advantages:

Extend_from_slice saves a capacity and length call on each individual byte, and does these checks just once for the entire slice.
Sometimes a call to extend_from_slice can avoid multiple allocations because it only needs to check the capacity once.
Vectorization can be used to copy multiple bytes much faster when done all at once.

You can find more about this Rust optimization in the Rust category on this site—look for the Vec extend_from_slice article.

Favorite Rust Feature

Rust is a powerful, modern language with many important features like memory safety, borrow checking, and zero-cost abstractions. My favorite Rust feature is something that is deeply involved in all of those things: the Arc struct.

With Arc, we have an atomic reference count type that we can wrap any other type inside. When we use an Arc, we can copy just the size of the Arc (8 bytes) instead of the actual type. And data inside an arc is guaranteed to be safe to access on many threads.

There are some limitations:

We cannot modify the data inside an Arc.
The syntax for wrapping other types inside Arcs can become a bit cumbersome.

Arc is best used when a program has multiple threads. When beginning to learn Rust, I remember changing a type to be encapsulated in an Arc, and then realizing a significant performance improvement when the amount of data copied to new threads was vastly decreased.

Single Source of Truth

One important principle in program design is having a single source of truth for a specific program state. So if you have several ways of determining if a Page is a Blog page, this can get confusing and result in bugs.

Instead, you should have just one place where the Page type is stored, and access it in a uniform way through the program. This principle is called the "single source of truth" and is well-known in computer science. It can be applied to many situations, including:

Programs (like with the Page example).
Databases, where only one table returns the result (rather than many tables).
More complex systems with multiple programs and databases.

As always, using caches to speed up access to this information can be problematic, as the cache ends up copying the single source of truth. Even when writing a simple program, relying on a unified, single source of truth is helpful.

Dark Mode Website Design

It has always been a dream of mine to build a cool-looking website. But a lot of my early ideas for web design were based around light mode—images that look fine on a white background only. My concepts did not work for dark mode.

Sure, I was able to change the background color to black, but this just looked awkward and unbalanced. Instead, for a "cool-looking" website that works in dark mode, it is necessary to have vector graphics (like SVG) that dynamically adjust to the color mode.

Here are some things I have learned:

Use "currentcolor" as a color in SVGs, and this will be modified when the user changes to dark or light mode.
Apply the "use" tag in SVG directly in HTML to access an icon from a SVG file (like a sprite sheet).
Avoid secondary colors as they are harder to adjust than "currentcolor."

It might not look as cool as I was hoping, but using SVG images works well for dark and light mode, and this benefits users who tend to prefer dark mode (like myself).

More
Dot Net Perls is a collection of pages with code examples, which are updated to stay current. Programming is an art, and it can be learned from examples.
Donate to this site to help offset the costs of running the server. Sites like this will cease to exist if there is no financial support for them.
Sam Allen is passionate about computer languages, and he maintains 100% of the material available on this website. He hopes it makes the world a nicer place.
An RSS feed is available for this blog.
Home
Changes
© 2007-2025 Sam Allen