|
3 | 3 | [](https://github.com/devlooped/go) |
4 | 4 |
|
5 | 5 | <!-- include ../../readme.md#content --> |
| 6 | +<!-- #content --> |
| 7 | + |
| 8 | +## What is `go#`? |
| 9 | + |
| 10 | +`go#` (go sharp) lets you run `.cs` files directly, like scripts, while still getting the full power of the .NET SDK (dependencies, compilation, AOT, etc.). |
| 11 | + |
| 12 | +It shines for: |
| 13 | +- Quick one-off tools and prototypes |
| 14 | +- File-based apps without a `.csproj` |
| 15 | +- Fast iteration with smart caching (subsequent runs are near-instant when nothing changed) |
| 16 | +- Easy sharing of small utilities (just the `.cs` file) |
| 17 | + |
| 18 | + |
| 19 | +## Usage |
| 20 | + |
| 21 | +```console |
| 22 | +# Run a file |
| 23 | +dnx go app.cs |
| 24 | + |
| 25 | +# Pass arguments to your app |
| 26 | +dnx go app.cs -- arg1 arg2 |
| 27 | + |
| 28 | +# Pass arguments to the underlying `dotnet publish` |
| 29 | +dnx go app.cs /p:MyProp=true -- arg1 arg2 |
| 30 | +``` |
| 31 | + |
| 32 | +The default mode publishes the app with native AOT and then runs the resulting executable, |
| 33 | +with smart up-to-date checks of every C# file used to build the app (including |
| 34 | +`#include` and `#ref` directives, transitively). |
| 35 | + |
| 36 | +Use `--r2r` when your app needs more dynamic .NET features (reflection, dynamic loading, etc.) |
| 37 | +that native AOT does not support, while still keeping most publish optimizations: |
| 38 | + |
| 39 | +```console |
| 40 | +dnx go app.cs --r2r |
| 41 | + |
| 42 | +# Pass arguments to your app |
| 43 | +dnx go app.cs --r2r -- arg1 arg2 |
| 44 | +``` |
| 45 | + |
| 46 | +This publishes with `/p:PublishAot=false` and `/p:PublishReadyToRun=true`. |
| 47 | +An equivalent `--aot` switch is not needed since native AOT is the default for file-based apps. |
| 48 | + |
| 49 | +A dev mode is also available for faster iteration, which skips the publish step |
| 50 | +and runs the app directly from the build output without the optimizations |
| 51 | +applied by dotnet to published executables (i.e. AOT, RID-specific optimizations): |
| 52 | + |
| 53 | +```console |
| 54 | +dnx go dev app.cs |
| 55 | + |
| 56 | +# Pass arguments to your app |
| 57 | +dnx go dev app.cs -- arg1 arg2 |
| 58 | + |
| 59 | +# Pass arguments to the underlying `dotnet run` |
| 60 | +dnx go dev app.cs /p:Configuration=Release -- arg1 arg2 |
| 61 | +``` |
| 62 | + |
| 63 | +## Cache and cleaning |
| 64 | + |
| 65 | +`go#` caches build and publish outputs per entry-point file under the |
| 66 | +user's temp area (`%TEMP%\dotnet\go` on Windows, |
| 67 | +`~/.local/share/dotnet/go` on Linux, `~/Library/Application Support/dotnet/go` on macOS), which is what makes |
| 68 | +unchanged re-runs near-instant. |
| 69 | + |
| 70 | +```console |
| 71 | +# Delete the cached artifacts for a single app (next run rebuilds) |
| 72 | +dnx go clean app.cs |
| 73 | + |
| 74 | +# Delete the cached artifacts for all apps |
| 75 | +dnx go clean --all |
| 76 | +``` |
| 77 | + |
| 78 | +Caches are also cleaned automatically: at most once every couple of days, |
| 79 | +`go#` removes cache directories that haven't been used for a while, in a |
| 80 | +detached background process. Apps you run regularly are never affected. |
| 81 | + |
| 82 | +## Performance |
| 83 | + |
| 84 | +The main advantage of `go#` is **fast unchanged re-runs**. |
| 85 | +The two core scenarios for `go#` file-based apps are: |
| 86 | +* While tweaking 👉 `dnx go dev app.cs` (optimized `dotnet run app.cs`) |
| 87 | +* When stable 👉 `dnx go app.cs` (optimized `dotnet publish app.cs; app[.exe]`) |
| 88 | + |
| 89 | +The numbers below showcase both scenarios, comparing `go#` to `dotnet run` and |
| 90 | +`dotnet publish` for a file-based app with different combinations of `#include` and `#ref` directives. |
| 91 | + |
| 92 | +<!-- ./artifacts/results/Benchmarks-report-github.md --> |
| 93 | +``` |
| 94 | +
|
| 95 | +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8737/25H2/2025Update/HudsonValley2) |
| 96 | +AMD Ryzen AI 9 HX 370 w/ Radeon 890M 2.00GHz, 1 CPU, 24 logical and 12 physical cores |
| 97 | +.NET SDK 11.0.100-preview.5.26302.115 |
| 98 | + [Host] : .NET 10.0.9 (10.0.9, 10.0.926.27113), X64 RyuJIT x86-64-v4 |
| 99 | + Job-TASYDQ : .NET 10.0.9 (10.0.9, 10.0.926.27113), X64 RyuJIT x86-64-v4 |
| 100 | +
|
| 101 | +InvocationCount=1 IterationCount=3 LaunchCount=1 |
| 102 | +UnrollFactor=1 WarmupCount=1 |
| 103 | +
|
| 104 | +``` |
| 105 | +| Method | Sample | Mean | Error | StdDev | |
| 106 | +|----------------- |---------------- |-----------:|------------:|---------:| |
| 107 | +| **'dnx go'** | **#include** | **483.2 ms** | **85.70 ms** | **4.70 ms** | |
| 108 | +| 'dotnet publish' | #include | 3,302.0 ms | 1,003.60 ms | 55.01 ms | |
| 109 | +| 'dnx go dev' | #include | 500.1 ms | 250.72 ms | 13.74 ms | |
| 110 | +| 'dotnet run' | #include | 475.6 ms | 100.88 ms | 5.53 ms | |
| 111 | +| **'dnx go'** | **#include + #ref** | **481.4 ms** | **236.79 ms** | **12.98 ms** | |
| 112 | +| 'dotnet publish' | #include + #ref | 3,474.3 ms | 391.66 ms | 21.47 ms | |
| 113 | +| 'dnx go dev' | #include + #ref | 498.3 ms | 290.97 ms | 15.95 ms | |
| 114 | +| 'dotnet run' | #include + #ref | 1,426.7 ms | 318.56 ms | 17.46 ms | |
| 115 | +| **'dnx go'** | **#ref** | **487.1 ms** | **140.05 ms** | **7.68 ms** | |
| 116 | +| 'dotnet publish' | #ref | 3,509.4 ms | 616.31 ms | 33.78 ms | |
| 117 | +| 'dnx go dev' | #ref | 505.2 ms | 264.59 ms | 14.50 ms | |
| 118 | +| 'dotnet run' | #ref | 1,413.9 ms | 267.93 ms | 14.69 ms | |
| 119 | +| **'dnx go'** | **minimal** | **480.8 ms** | **486.66 ms** | **26.68 ms** | |
| 120 | +| 'dotnet publish' | minimal | 3,237.4 ms | 567.55 ms | 31.11 ms | |
| 121 | +| 'dnx go dev' | minimal | 488.4 ms | 209.11 ms | 11.46 ms | |
| 122 | +| 'dotnet run' | minimal | 482.5 ms | 507.46 ms | 27.82 ms | |
| 123 | + |
| 124 | +<!-- ./artifacts/results/Benchmarks-report-github.md --> |
| 125 | + |
| 126 | +<!-- #content --> |
| 127 | +<!-- ../../readme.md#content --> |
6 | 128 |
|
7 | 129 | <!-- include https://github.com/devlooped/.github/raw/main/osmf.md --> |
| 130 | +## Open Source Maintenance Fee |
| 131 | + |
| 132 | +To ensure the long-term sustainability of this project, users of this package who generate |
| 133 | +revenue must pay an [Open Source Maintenance Fee](https://opensourcemaintenancefee.org). |
| 134 | +While the source code is freely available under the terms of the [License](license.txt), |
| 135 | +this package and other aspects of the project require [adherence to the Maintenance Fee](osmfeula.txt). |
| 136 | + |
| 137 | +To pay the Maintenance Fee, [become a Sponsor](https://github.com/sponsors/devlooped) at the proper |
| 138 | +OSMF tier. A single fee covers all of [Devlooped packages](https://www.nuget.org/profiles/Devlooped). |
| 139 | + |
| 140 | +<!-- https://github.com/devlooped/.github/raw/main/osmf.md --> |
8 | 141 |
|
9 | 142 | <!-- include https://github.com/devlooped/sponsors/raw/main/footer.md --> |
| 143 | +# Sponsors |
| 144 | + |
| 145 | +<!-- sponsors.md --> |
| 146 | +[](https://github.com/clarius) |
| 147 | +[](https://github.com/MFB-Technologies-Inc) |
| 148 | +[](https://github.com/sandrock) |
| 149 | +[](https://github.com/drivenet) |
| 150 | +[](https://github.com/Keflon) |
| 151 | +[](https://github.com/tbolon) |
| 152 | +[](https://github.com/kfrancis) |
| 153 | +[](https://github.com/rbnswartz) |
| 154 | +[](https://github.com/jfoshee) |
| 155 | +[](https://github.com/Mrxx99) |
| 156 | +[](https://github.com/eajhnsn1) |
| 157 | +[](https://github.com/Jonathan-Hickey) |
| 158 | +[](https://github.com/KenBonny) |
| 159 | +[](https://github.com/SimonCropp) |
| 160 | +[](https://github.com/agileworks-eu) |
| 161 | +[](https://github.com/arsdragonfly) |
| 162 | +[](https://github.com/vezel-dev) |
| 163 | +[](https://github.com/ChilliCream) |
| 164 | +[](https://github.com/4OTC) |
| 165 | +[](https://github.com/DominicSchell) |
| 166 | +[](https://github.com/adalon) |
| 167 | +[](https://github.com/torutek) |
| 168 | +[](https://github.com/mccaffers) |
| 169 | +[](https://github.com/SeikaLogiciel) |
| 170 | +[](https://github.com/wizardness) |
| 171 | +[](https://github.com/eska-gmbh) |
| 172 | +[](https://github.com/geodata-no) |
| 173 | + |
| 174 | + |
| 175 | +<!-- sponsors.md --> |
| 176 | +[](https://github.com/sponsors/devlooped) |
| 177 | + |
| 178 | +[Learn more about GitHub Sponsors](https://github.com/sponsors) |
| 179 | + |
| 180 | +<!-- https://github.com/devlooped/sponsors/raw/main/footer.md --> |
0 commit comments