Fiber v1.9.6 πŸ”₯ How to improve performance by 817% and stay fast, flexible and friendly?

koddr

Vic ShΓ³stak

Posted on May 9, 2020

Fiber v1.9.6 πŸ”₯ How to improve performance by 817% and stay fast, flexible and friendly?

Introduction

Hey, gophers and Fiber community πŸ‘‹

I missed the beginning of the v1.9.x branch of our favorite framework... but the news I will bring you today is worth all the waiting! I promise, you'll be a happy gopher!

OK! Let's go to v1.9.6 πŸš€

πŸ“ Table of contents

Fast part

βœ… New router

Now, we improved router performance by 817% and removed all allocations in hot paths.



# Fiber v1.9.4 and lower
Benchmark_Router_OLD-4      614   2467460 ns/op   68902 B/op   600 allocs/op

# Fiber from v1.9.6 and higher
Benchmark_Router_NEW-4     3429    302033 ns/op       0 B/op     0 allocs/op


Enter fullscreen mode Exit fullscreen mode

How did we do that? 🀷 Oh, let me explain!

As you know, we used Go's regex package to parse routes with parameters. But Go's regex is not optimized compared to other languages. Therefore, we used experience of the ucarion/urlpath package to rethink a route matching strategy for Fiber. With the help of @renewerner87 we manged to ditch regexp completely.

But, how does it really works? πŸ€” Let's check out the original repo docs...

urlpath operates on the basis of "segments", which is basically the result of splitting a path by slashes. When you call urlpath.New, each of the segments in the input is treated as either:

  • A parameterized segment, like :user. All segments starting with : are considered parameterized. Any corresponding segment in the input (even the empty string!) will be satisfactory, and will be sent to Params in the outputted Match. For example, data corresponding to :user would go in Params["user"].
  • An exact-match segment, like users. Only segments exactly equal to users will be satisfactory.
  • A "trailing" segment, *. This is only treated specially when it's the last segment β€” otherwise, it's just a usual exact-match segment. Any leftover data in the input, after all previous segments were satisfied, goes into Trailing in the outputted Match.

We're very grateful to ucarion/urlpath authors!

Example code to reproduce benchmark, you can see on Fiber repository tests for the router. Just install v1.9.6 or higher, run benchmark and then, downgrade to lower version and run again.

πŸ’‘ Remove dependencies

Branch v1.9.x focused on speed and simplicity. Therefore, all maintainers are looking for different ways to remove unnecessary dependencies. And, unfortunately, we would like to say "thank you and good bye" to json-iterator/go package... because, what could be better than a faster built-in package for working with JSON in Go 1.14 πŸ˜‰



# goos: linux/amd64
BenchmarkJsoniter-4    980358     1061 ns/op   72 B/op    3 allocs/op
BenchmarkJson-4        1177653    1007 ns/op   64 B/op    2 allocs/op

# goos: windows/amd64
BenchmarkJsoniter-4    4473760    259 ns/op    72 B/op    3 allocs/op
BenchmarkJson-4        4625077    251 ns/op    64 B/op    2 allocs/op

# goos: darwin/amd64
BenchmarkJsoniter-4    2059158    801 ns/op    72 B/op    3 allocs/op
BenchmarkJson-4        2738658    400 ns/op    64 B/op    2 allocs/op


Enter fullscreen mode Exit fullscreen mode

Example code to reproduce benchmark:



import (
    "testing"
    json "encoding/json"
    jsoniter "github.com/json-iterator/go"
)

type JSONData struct {
    Name string
    Age  uint8
}

var jsoniterParser = jsoniter.ConfigCompatibleWithStandardLibrary

func BenchmarkJsoniter(b *testing.B) {
    for n := 0; n < b.N; n++ {
        data := JSONData{
            Name: "John",
            Age:  20,
        }
        _, _ = jsoniterParser.Marshal(&data)
    }
}

func BenchmarkJson(b *testing.B) {
    for n := 0; n < b.N; n++ {
        data := JSONData{
            Name: "John",
            Age:  20,
        }
        _, _ = json.Marshal(&data)
    }
}


Enter fullscreen mode Exit fullscreen mode

Run benchmark to see result for your PC/Mac:



go test -benchmem -run=^$ -bench .


Enter fullscreen mode Exit fullscreen mode

βš™οΈ Dependency graph for v1.9.x

When you execute go get -u github.com/gofiber/fiber command, you will see only such dependencies:

dependency graph

Flexible part

🧬 Official middlewares

For an more maintainable middleware ecosystem, we've put official middlewares into separate repositories:

🌱 Third-party middlewares

This is a list of middlewares, that are created by the Fiber community:

Friendly part

πŸŽ™ Discord channel

Oh, yes! It finally happened! πŸŽ‰ Fiber community now has a place to communicate and share experiences β€” official Discord channel.

discord channel

Come on in, it'll be nice to talk to you! πŸ˜‰

🈯️ Translation

Special greetings, I would like to give a shoutout to all the people who helped translating the fiber documentation. You're awesome, thank you so much! πŸ‘

translation

If you would like to help translate and/or improve an existing translation, then welcome to our Crowdin!

⭐️ Startup message

Sometimes, they come back 🀣



        _______ __
  ____ / ____(_) /_  ___  _____
_____ / /_  / / __ \/ _ \/ ___/
  __ / __/ / / /_/ /  __/ /
    /_/   /_/_.___/\___/_/ v1.9.6
Started listening on 0.0.0.0:3000


Enter fullscreen mode Exit fullscreen mode

When Settings.DisableStartupMessage set to true, it will not print out the Fiber ASCII logo and "listening on ..." message.

πŸ˜‹ My short history with the Fiber project

My story with Fiber web framework doesn't end with "consumption" alone. After translating README into Russian and creating the first concepts of the official logo, I got acquainted with the author and invited to be an official maintainer. Our route to bring Fiber to the public begon.

@fenny, if you're reading this, know you're really awesome! 😘

Let's go back to early February 2020, Fiber had:

  • No more than 120 GitHub stars;
  • A weird logo (as Fenny suggested: "gopher holding a fiber optic cable?");
  • No translations

Decisions on architecture, naming, versioning, code & method design, testing and benchmarks of web framework... were discussed every evening directly on messenger with a cup of coffee in the best possible way.

Here's a v1.3.0 release showing how much Fenny adores me πŸ˜‚:

release 1.3.0

I still cannot believe that after 2,5 months since the first release, Fiber web framework has:

🎯 5,200+ stars on GitHub;
🎯 Stably gets into GitHub Trending page of Golang (weekly, daily);
🎯 Big, friendly (and alive) community coming from all over the world;
🎯 Documentation, translated into 12 languages (and preparing another six);
🎯 Identical API and method names as Express;
🎯 An actively developing middleware ecosystem;
🎯 TOP-2 status among all Go web frameworks and TOP-10 among all other programming languages, according to different benchmarks (TechEmpower, The Benchmarker and not so);

release 1.9.6

πŸ’¬ Do you like Fiber? Tell about it!

Fiber authors are always listening to its users in issues, Discord channel and all over the Internet. Therefore, it would be great, if you could share your opinion or/and experience with Fiber to authors in GitHub repository!

[...] because it's only right way to create a fast, flexible and friendly Go web framework for any tasks, deadlines and developer skills!

β€” Fiber Authors

Do you like Fiber?

Your assistance to project πŸ‘

  1. Add a GitHub Star to the project.
  2. Tweet about the project on your Twitter.
  3. Write a review or tutorial on Medium, Dev.to or personal blog.
  4. Help us to translate our API Documentation via Crowdin.

Photo by

[Title] Matthew Brodeur (link) & Vic ShΓ³stak (link)
[1] Discord https://discord.com/download
[2] Ashley McNamara https://github.com/ashleymcnamara/gophers

P.S.

If you want more articles (like this) on this blog, then post a comment below and subscribe to me. Thanks! 😻

❗️ You can support me on Boosty, both on a permanent and on a one-time basis. All proceeds from this way will go to support my OSS projects and will energize me to create new products and articles for the community.

support me on Boosty

And of course, you can help me make developers' lives even better! Just connect to one of my projects as a contributor. It's easy!

My main projects that need your help (and stars) πŸ‘‡

  • πŸ”₯ gowebly: A next-generation CLI tool that makes it easy to create amazing web applications with Go on the backend, using htmx, hyperscript or Alpine.js and the most popular CSS frameworks on the frontend.
  • ✨ create-go-app: Create a new production-ready project with Go backend, frontend and deploy automation by running one CLI command.

Other my small projects: yatr, gosl, json2csv, csv2api.

πŸ’– πŸ’ͺ πŸ™… 🚩
koddr
Vic ShΓ³stak

Posted on May 9, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related