<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Tedd’s blog</title><link>https://blog.tedd.no/</link><description>Notes on software, systems, and the details that make them work. C#, .NET, performance, and engineering by Tedd.</description><language>en</language><atom:link href="https://blog.tedd.no/feed.xml" rel="self" type="application/rss+xml"/><item><title>Unsafe reference arithmetic in .NET</title><link>https://blog.tedd.no/2022/03/07/unsafe-reference-arithmetic-in-net/</link><guid isPermaLink="true">https://blog.tedd.no/2022/03/07/unsafe-reference-arithmetic-in-net/</guid><pubDate>Mon, 07 Mar 2022 22:14:31 GMT</pubDate><description>A closer look at CompilerServices.Unsafe as the modern alternative to the fixed statement: doing reference arithmetic on GC-managed memory without pinning, what &quot;unsafe&quot; really means, and what the CLR does and doesn&#39;t promise you.</description><category>C#</category><category>Performance</category><category>.NET</category><category>MSIL</category></item><item><title>Why C# multidimensional arrays are slow</title><link>https://blog.tedd.no/2021/10/07/why-c-multidimensional-arrays-are-slow/</link><guid isPermaLink="true">https://blog.tedd.no/2021/10/07/why-c-multidimensional-arrays-are-slow/</guid><pubDate>Thu, 07 Oct 2021 14:37:44 GMT</pubDate><description>int[,] looks like the natural choice and performs like the wrong one. Digging into IL and JIT output to show what actually happens when you access single-dimensional, multidimensional and jagged arrays — and why the rectangular one loses.</description><category>C#</category><category>Performance</category><category>MSIL</category><category>Benchmark</category></item><item><title>Faster C# array access</title><link>https://blog.tedd.no/2020/06/01/faster-c-array-access/</link><guid isPermaLink="true">https://blog.tedd.no/2020/06/01/faster-c-array-access/</guid><pubDate>Mon, 01 Jun 2020 15:18:48 GMT</pubDate><description>Every array access in .NET pays for a bounds check — unless you convince the compiler it can skip it. I read the JIT&#39;ed x64 assembly and benchmark tricks that make plain array access 18-34% faster.</description><category>C#</category><category>Performance</category><category>MSIL</category><category>Benchmark</category></item><item><title>Automatic unlock QNAP volumes from network</title><link>https://blog.tedd.no/2020/05/24/automatic-unlock-qnap-volumes-from-network/</link><guid isPermaLink="true">https://blog.tedd.no/2020/05/24/automatic-unlock-qnap-volumes-from-network/</guid><pubDate>Sun, 24 May 2020 09:58:02 GMT</pubDate><description>Encrypted QNAP volumes protect against stolen hardware, but someone must enter the key after every power loss. This BASH script in a cron job on another machine logs in, finds locked volumes and unlocks them automatically — security without the 3AM wake-up.</description><category>Admin</category><category>Encryption</category><category>Storage</category><category>Linux</category></item><item><title>Demystifying async/await (with memes)</title><link>https://blog.tedd.no/2020/05/07/demystifying-async-await/</link><guid isPermaLink="true">https://blog.tedd.no/2020/05/07/demystifying-async-await/</guid><pubDate>Thu, 07 May 2020 18:44:19 GMT</pubDate><description>Async/await looks simple and is widely misunderstood — I have seen entire conference talks get it wrong. A trip down the rabbit hole with examples (and memes) of what the compiler actually does: no, async does not create a thread.</description><category>C#</category><category>Async</category><category>.NET</category></item><item><title>Recompress zip-files (PowerShell)</title><link>https://blog.tedd.no/2020/04/13/recompress-zip-files-powershell/</link><guid isPermaLink="true">https://blog.tedd.no/2020/04/13/recompress-zip-files-powershell/</guid><pubDate>Mon, 13 Apr 2020 10:32:27 GMT</pubDate><description>A PowerShell script that recursively re-compresses ZIP files with 7-Zip at maximum settings (Deflate64), reporting how much space each file saved.</description><category>PowerShell</category><category>Compression</category><category>Tips</category></item><item><title>ASP.NET Core TypeScript</title><link>https://blog.tedd.no/2019/06/25/asp-net-core-typescript/</link><guid isPermaLink="true">https://blog.tedd.no/2019/06/25/asp-net-core-typescript/</guid><pubDate>Tue, 25 Jun 2019 10:20:06 GMT</pubDate><description>Part of my ASP.NET Core recipe series: compiling TypeScript as part of the project so the frontend gets types too.</description><category>ASP.NET Core</category><category>TypeScript</category><category>ASP.NET</category></item><item><title>ASP.NET Core memory cache</title><link>https://blog.tedd.no/2019/06/25/asp-net-core-memory-cache/</link><guid isPermaLink="true">https://blog.tedd.no/2019/06/25/asp-net-core-memory-cache/</guid><pubDate>Tue, 25 Jun 2019 10:05:53 GMT</pubDate><description>Part of my ASP.NET Core recipe series: using the built-in memory cache for data you don&#39;t want to fetch on every request.</description><category>ASP.NET Core</category><category>C#</category><category>ASP.NET</category></item><item><title>ASP.NET Core response cache</title><link>https://blog.tedd.no/2019/06/25/asp-net-core-response-cache/</link><guid isPermaLink="true">https://blog.tedd.no/2019/06/25/asp-net-core-response-cache/</guid><pubDate>Tue, 25 Jun 2019 10:00:31 GMT</pubDate><description>Part of my ASP.NET Core recipe series: enabling response caching so identical requests are served without re-executing the pipeline.</description><category>ASP.NET Core</category><category>C#</category><category>ASP.NET</category></item><item><title>ASP.NET Core AutoMapper</title><link>https://blog.tedd.no/2019/06/20/asp-net-core-automapper/</link><guid isPermaLink="true">https://blog.tedd.no/2019/06/20/asp-net-core-automapper/</guid><pubDate>Thu, 20 Jun 2019 11:35:22 GMT</pubDate><description>Part of my ASP.NET Core recipe series: wiring up AutoMapper to map between entities and view/API models without hand-written copy code.</description><category>ASP.NET Core</category><category>C#</category><category>ASP.NET</category></item><item><title>EF Core in separate project</title><link>https://blog.tedd.no/2019/06/20/ef-core-in-separate-project/</link><guid isPermaLink="true">https://blog.tedd.no/2019/06/20/ef-core-in-separate-project/</guid><pubDate>Thu, 20 Jun 2019 11:30:36 GMT</pubDate><description>Part of my ASP.NET Core recipe series: moving EF Core into its own project so the data layer stays separated from the web application.</description><category>ASP.NET Core</category><category>EF Core</category><category>C#</category><category>ASP.NET</category></item><item><title>ASP.NET Core API with Swagger UI</title><link>https://blog.tedd.no/2019/06/20/asp-net-core-api-with-swagger-ui/</link><guid isPermaLink="true">https://blog.tedd.no/2019/06/20/asp-net-core-api-with-swagger-ui/</guid><pubDate>Thu, 20 Jun 2019 11:25:08 GMT</pubDate><description>Part of my ASP.NET Core recipe series: exposing your API with Swagger UI so it documents and exercises itself.</description><category>ASP.NET Core</category><category>C#</category><category>ASP.NET</category></item><item><title>ASP.NET Core API versioning</title><link>https://blog.tedd.no/2019/06/20/asp-net-core-api-versioning/</link><guid isPermaLink="true">https://blog.tedd.no/2019/06/20/asp-net-core-api-versioning/</guid><pubDate>Thu, 20 Jun 2019 10:20:08 GMT</pubDate><description>Part of my ASP.NET Core recipe series: adding API versioning so /api/v1/ and /api/v2/ can coexist while clients migrate at their own pace.</description><category>ASP.NET Core</category><category>C#</category><category>ASP.NET</category></item><item><title>ASP.NET Core MVC with /api/-area</title><link>https://blog.tedd.no/2019/06/20/asp-net-core-mvc-with-api-area/</link><guid isPermaLink="true">https://blog.tedd.no/2019/06/20/asp-net-core-mvc-with-api-area/</guid><pubDate>Thu, 20 Jun 2019 10:15:34 GMT</pubDate><description>Part of my ASP.NET Core recipe series: carving out an /api/-area in an MVC project so pages and API endpoints live cleanly side by side.</description><category>ASP.NET Core</category><category>C#</category><category>MVC</category><category>ASP.NET</category></item><item><title>ASP.NET Core managed config</title><link>https://blog.tedd.no/2019/06/20/asp-net-core-managed-config/</link><guid isPermaLink="true">https://blog.tedd.no/2019/06/20/asp-net-core-managed-config/</guid><pubDate>Thu, 20 Jun 2019 10:10:03 GMT</pubDate><description>Part of my ASP.NET Core recipe series: binding appsettings.json to typed config classes so settings are managed code instead of magic strings.</description><category>ASP.NET Core</category><category>C#</category><category>Configuration</category><category>ASP.NET</category></item><item><title>ASP.NET Core logging with Serilog</title><link>https://blog.tedd.no/2019/06/20/asp-net-core-logging-with-serilog/</link><guid isPermaLink="true">https://blog.tedd.no/2019/06/20/asp-net-core-logging-with-serilog/</guid><pubDate>Thu, 20 Jun 2019 10:05:15 GMT</pubDate><description>Part of my ASP.NET Core recipe series: replacing the default logging with Serilog for structured logs with proper sinks.</description><category>ASP.NET Core</category><category>C#</category><category>ASP.NET</category></item><item><title>ASP.NET Core MVC</title><link>https://blog.tedd.no/2019/06/20/asp-net-core-mvc/</link><guid isPermaLink="true">https://blog.tedd.no/2019/06/20/asp-net-core-mvc/</guid><pubDate>Thu, 20 Jun 2019 10:00:19 GMT</pubDate><description>The opening recipe in my ASP.NET Core series: setting up a clean MVC project as the foundation the rest of the recipes build on.</description><category>ASP.NET Core</category><category>C#</category><category>MVC</category><category>ASP.NET</category></item><item><title>Extension support for .Net Core application</title><link>https://blog.tedd.no/2019/05/07/extension-support-for-net-core-application/</link><guid isPermaLink="true">https://blog.tedd.no/2019/05/07/extension-support-for-net-core-application/</guid><pubDate>Tue, 07 May 2019 14:19:25 GMT</pubDate><description>Plugins for a .NET Core app boil down to loading .dlls at runtime, finding the interesting interfaces and registering them in IoC. Since IoC already gives you loose coupling, dynamic loading is a small step — shown here.</description><category>.NET Core</category><category>C#</category></item><item><title>.Net Core Console Application IoC</title><link>https://blog.tedd.no/2019/05/07/net-core-console-application-ioc/</link><guid isPermaLink="true">https://blog.tedd.no/2019/05/07/net-core-console-application-ioc/</guid><pubDate>Tue, 07 May 2019 12:31:53 GMT</pubDate><description>MVC gets IoC boilerplate generated for free; console apps don&#39;t. With HostBuilder from the Generic Host it&#39;s easy to wire up the same dependency injection, config and logging in a console application — here is the boilerplate.</description><category>.NET Core</category><category>C#</category></item><item><title>Benchmarking dynamic method invocation in .Net</title><link>https://blog.tedd.no/2018/12/30/benchmarking-dynamic-method-invocation-in-net/</link><guid isPermaLink="true">https://blog.tedd.no/2018/12/30/benchmarking-dynamic-method-invocation-in-net/</guid><pubDate>Sun, 30 Dec 2018 12:21:59 GMT</pubDate><description>Interface, base class, virtual, override, dynamic, reflection or expression trees — .NET gives you many ways to call a method, and their costs differ wildly. Full benchmark with numbers for each.</description><category>C#</category><category>Benchmark</category><category>Performance</category><category>MSIL</category></item><item><title>Building a voxel engine like Minecraft in Unity (2 of 2)</title><link>https://blog.tedd.no/2018/12/22/building-a-voxel-engine-part-2/</link><guid isPermaLink="true">https://blog.tedd.no/2018/12/22/building-a-voxel-engine-part-2/</guid><pubDate>Sat, 22 Dec 2018 15:34:11 GMT</pubDate><description>Part 2 of the voxel engine introduction: turning chunk data into renderable polygon meshes in Unity, one Mesh per chunk, and only drawing the faces that can actually be seen.</description><category>Unity</category><category>Game Development</category><category>C#</category></item><item><title>Building a voxel engine like Minecraft in Unity (1 of 2)</title><link>https://blog.tedd.no/2018/12/22/building-a-voxel-engine-part-1/</link><guid isPermaLink="true">https://blog.tedd.no/2018/12/22/building-a-voxel-engine-part-1/</guid><pubDate>Sat, 22 Dec 2018 15:31:45 GMT</pubDate><description>My Christmas vacation project: a basic introduction to voxel engines à la Minecraft. Part 1 covers what voxels are, polygon meshes, and how to represent a voxel world in memory without hitting limits.</description><category>Unity</category><category>Game Development</category><category>C#</category></item><item><title>Code sharing between VS and Unity 3D</title><link>https://blog.tedd.no/2018/12/08/code-sharing-between-vs-and-unity-3d/</link><guid isPermaLink="true">https://blog.tedd.no/2018/12/08/code-sharing-between-vs-and-unity-3d/</guid><pubDate>Sat, 08 Dec 2018 16:37:57 GMT</pubDate><description>Unity happily lets you write C# but not structure it. Four ways to share code between proper Visual Studio projects and Unity — so your libraries stay testable and your Unity project stops being a big ball of mud.</description><category>Unity</category><category>Visual Studio</category><category>C#</category><category>.NET</category></item><item><title>Setting up new .Net projects</title><link>https://blog.tedd.no/2018/06/20/setting-up-new-net-projects/</link><guid isPermaLink="true">https://blog.tedd.no/2018/06/20/setting-up-new-net-projects/</guid><pubDate>Wed, 20 Jun 2018 10:13:33 GMT</pubDate><description>After ~30 years and a few thousand projects, this is how I set up new .NET solutions: naming, project structure, .NET Standard vs Core choices — and the reasoning behind each habit. Not a book on architecture, just a clean, consistent setup.</description><category>.NET</category><category>C#</category><category>Visual Studio</category><category>ASP.NET</category></item><item><title>sizeof() vs Marshal.SizeOf()</title><link>https://blog.tedd.no/2018/03/18/sizeof-vs-marshal-sizeof/</link><guid isPermaLink="true">https://blog.tedd.no/2018/03/18/sizeof-vs-marshal-sizeof/</guid><pubDate>Sun, 18 Mar 2018 23:12:00 GMT</pubDate><description>sizeof() compiles to a constant; Marshal.SizeOf() measures the marshaled struct at runtime. What each one really returns, what it costs, and when to use which — with IL to prove it.</description><category>C#</category><category>MSIL</category><category>Benchmark</category></item><item><title>Cost of method wrapper</title><link>https://blog.tedd.no/2018/01/17/cost-of-method-wrapper/</link><guid isPermaLink="true">https://blog.tedd.no/2018/01/17/cost-of-method-wrapper/</guid><pubDate>Wed, 17 Jan 2018 00:08:56 GMT</pubDate><description>What does a method that just calls another method actually cost? Using the == operator vs IEquatable.Equals as the guinea pig, I benchmark wrapper calls across compilers, JITs and runtimes — and read the disassembly to see why.</description><category>C#</category><category>MSIL</category><category>Benchmark</category><category>Performance</category></item><item><title>Speeding up Unitys Vector in lists/dictionaries</title><link>https://blog.tedd.no/2018/01/13/speeding-up-unitys-vector-in-lists-dictionaries/</link><guid isPermaLink="true">https://blog.tedd.no/2018/01/13/speeding-up-unitys-vector-in-lists-dictionaries/</guid><pubDate>Sat, 13 Jan 2018 12:40:08 GMT</pubDate><description>Unity&#39;s Vector2/3/4 and Quaternion lack IEquatable and have a poor GetHashCode, which quietly murders performance the moment you put them in lists or dictionaries. Measurements, explanation, and the fix I reported to Unity.</description><category>Unity</category><category>C#</category><category>Performance</category><category>Benchmark</category></item><item><title>Simple app.config appSettings deserializer (with tree structure)</title><link>https://blog.tedd.no/2017/10/30/simple-app-config-appsettings-deserializer-with-tree-structure/</link><guid isPermaLink="true">https://blog.tedd.no/2017/10/30/simple-app-config-appsettings-deserializer-with-tree-structure/</guid><pubDate>Mon, 30 Oct 2017 23:54:56 GMT</pubDate><description>Reading appSettings shouldn&#39;t require custom sections, XML readers or per-access string conversion. A small base class that maps keys like Config.SmtpClient.Host to a typed tree, converted once at startup.</description><category>C#</category><category>Configuration</category></item><item><title>Automatic class generator for CsvHelper</title><link>https://blog.tedd.no/2017/09/26/automatic-class-generator-for-csvhelper/</link><guid isPermaLink="true">https://blog.tedd.no/2017/09/26/automatic-class-generator-for-csvhelper/</guid><pubDate>Tue, 26 Sep 2017 13:16:45 GMT</pubDate><description>CsvHelper is great, but writing the model and mapper classes is tedious. Paste your CSV header on this page and it generates both classes for you.</description><category>C#</category><category>Tools</category></item><item><title>IIS redirect HTTP to HTTPS but allow Let&#39;s Encrypt</title><link>https://blog.tedd.no/2017/05/09/iis-redirect-http-to-https-but-allow-lets-encrypt/</link><guid isPermaLink="true">https://blog.tedd.no/2017/05/09/iis-redirect-http-to-https-but-allow-lets-encrypt/</guid><pubDate>Tue, 09 May 2017 16:11:14 GMT</pubDate><description>Redirecting all HTTP to HTTPS in IIS breaks Let&#39;s Encrypt&#39;s renewal challenge. Two URL Rewrite rules fix it: let .well-known through, redirect everything else.</description><category>IIS</category><category>Security</category><category>Admin</category></item></channel></rss>