All Projects β†’ haskell-perf β†’ Checklist

haskell-perf / Checklist

Licence: gpl-3.0
The Haskell performance checklist

Programming Languages

haskell
3896 projects

Projects that are alternatives of or similar to Checklist

Waterdrop
πŸ’§Waterdrop is a high performance micro service framework. Waterdrop comes from (The Three Body Problem).
Stars: ✭ 305 (-10.29%)
Mutual labels:  performance
Viperhtml
Isomorphic hyperHTML
Stars: ✭ 318 (-6.47%)
Mutual labels:  performance
Guzzle Cache Middleware
A HTTP Cache for Guzzle 6. It's a simple Middleware to be added in the HandlerStack.
Stars: ✭ 325 (-4.41%)
Mutual labels:  performance
Wipe Modules
πŸ—‘οΈ Easily remove the node_modules folder of non-active projects
Stars: ✭ 304 (-10.59%)
Mutual labels:  performance
Async Techniques Python Course
Async Techniques and Examples in Python Course
Stars: ✭ 314 (-7.65%)
Mutual labels:  performance
Sqlbench
sqlbench measures and compares the execution time of one or more SQL queries.
Stars: ✭ 319 (-6.18%)
Mutual labels:  performance
T1ha
One of the fastest hash functions
Stars: ✭ 302 (-11.18%)
Mutual labels:  performance
Akarin
Akarin is a powerful (not yet) server software from the 'new dimension'
Stars: ✭ 332 (-2.35%)
Mutual labels:  performance
Fperf
Framework of performance testing
Stars: ✭ 316 (-7.06%)
Mutual labels:  performance
Tune
The Ultimate .NET Experiment
Stars: ✭ 324 (-4.71%)
Mutual labels:  performance
Cpptrader
High performance components for building Trading Platform such as ultra fast matching engine, order book processor
Stars: ✭ 308 (-9.41%)
Mutual labels:  performance
Performance
πŸ’ͺ Models' quality and performance metrics (R2, ICC, LOO, AIC, BF, ...)
Stars: ✭ 311 (-8.53%)
Mutual labels:  performance
Webapp Checklist
Technical details that a programmer of a web application should consider before making the site public.
Stars: ✭ 320 (-5.88%)
Mutual labels:  performance
Memoize State
The magic memoization for the State management. ✨🧠
Stars: ✭ 305 (-10.29%)
Mutual labels:  performance
Doraemonkit
δΈ€ζ¬Ύι’ε‘ζ³›ε‰η«―δΊ§ε“η ”ε‘ε…¨η”Ÿε‘½ε‘¨ζœŸηš„ζ•ˆηŽ‡εΉ³ε°γ€‚
Stars: ✭ 18,305 (+5283.82%)
Mutual labels:  performance
Three Mesh Bvh
A BVH implementation to speed up raycasting against three.js meshes.
Stars: ✭ 302 (-11.18%)
Mutual labels:  performance
Laravel S
LaravelS is an out-of-the-box adapter between Swoole and Laravel/Lumen.
Stars: ✭ 3,479 (+923.24%)
Mutual labels:  performance
Arrayfire
ArrayFire: a general purpose GPU library.
Stars: ✭ 3,693 (+986.18%)
Mutual labels:  performance
Fastify
Fast and low overhead web framework, for Node.js
Stars: ✭ 21,489 (+6220.29%)
Mutual labels:  performance
React Shrine
"Shrine" Progressive Web App sample built with React
Stars: ✭ 322 (-5.29%)
Mutual labels:  performance

The Haskell performance checklist

You have a Haskell program that's not performing how you'd like. Use this list to check that you've done the usual steps to performance nirvana:

βœ“ Are you compiling it?

βœ“ Are you compiling with -Wall?

βœ“ Are you compiling with -O or above?

βœ“ Have you run your code with the profiler?

βœ“ Have you checked for stack space leaks?

βœ“ Have you setup an isolated benchmark?

βœ“ Have you looked at strictness of your function arguments?

βœ“ Are you using the right data structure?

βœ“ Are your data types strict and/or unpacked?

βœ“ Did you check your code isn't too polymorphic?

βœ“ Do you have an explicit export list?

βœ“ Have you looked at the Core?

βœ“ Have you considered unboxed arrays/strefs/etc?

βœ“ Are you using Text or ByteString instead of String?

βœ“ Have you considered compiling with LLVM?

Are you compiling it?

Running code in GHCi's interpreter will always be much slower than compiling it to a binary.

Make sure you're compiling your code with ghc.

Are you compiling with -Wall?

GHC warns about type defaults and missing type signatures:

  • If you let GHC default integers, it will choose Integer. This is 10x slower than Int. So make sure you explicitly choose your types.
  • You should have explicit types to not miss something obvious in the types that is slow.

Are you compiling with -O or above?

By default GHC does not optimize your programs. Cabal and Stack enable this in the build process. If you're calling ghc directly, don't forget to add -O.

Enable -O2 for serious, non-dangerous optimizations.

Have you run your code with the profiler?

Profiling is the standard way to see for expressions in your program:

  1. How many times they run?
  2. How much do they allocate?

Resources on profiling:

Did you try weighing your operations?

Check that your operations aren't allocating too much or more than you'd expect:

https://github.com/fpco/weigh#readme

Allocating in GC is claimed to be "fast" but not allocating is always faster.

Have you checked for stack space leaks?

Most space leaks result in an excess use of stack. If you look for the part of the program that results in the largest stack usage, that is the most likely space leak, and the one that should be investigated first.

Resource on stack space leak:

Have you setup an isolated benchmark?

Benchmarking is a tricky business to get right, especially when timing things at a smaller scale. Haskell is lucky to have a very good benchmarking package. If you are asking someone for help, you are helping them by providing benchmarks, and they are likely to ask for them.

Do it right and use Criterion.

Resources on Criterion:

Have you looked at strictness of your function arguments?

https://wiki.haskell.org/Performance/Strictness

Are you using the right data structure?

This GitHub organization provides comparative benchmarks against a few types of data structures. You can often use this to determine which data structure is best for your problem:

  • sets - for set-like things
  • dictionaries - dictionaries, hashmaps, maps, etc.
  • sequences - lists, vectors/arrays, sequences, etc.

Tip: Lists are almost always the wrong data structure. But sometimes they are the right one.

See also HaskellWiki on data structures.

Are your data types strict and/or unpacked?

By default, Haskell fields are lazy and boxed. Making them strict can often (not always) give them more predictable performance, and unboxed fields (such as integers) do not require pointer indirection.

Resources on data type strictness:

Did you check your code isn't too polymorphic?

Code which is type-class-polymorphic, such as,

genericLength :: Num n => [a] -> n

has to accept an additional dictionary argument for which class instance you want to use for Num. That can make things slower.

Resources on overloading:

Do you have an explicit export list?

This is a suggestion from the HaskellWiki, but I believe it's based on out of date information about how GHC does inlining. It's left here for interested parties, however.

https://wiki.haskell.org/Performance/Modules

Have you looked at the Core?

Haskell compiles down to a small language, Core, which represents the real code generated before assembly. This is where many optimization passes take place.

Resources on core:

Have you considered unboxed arrays/strefs/etc?

An array with boxed elements such as Data.Vector.Vector a means each element is a pointer to the value, instead of containing the values inline.

Use an unboxed vector where you can (integers and atomic types like that) to avoid the pointer indirection. The vector may be stored and accessed in the CPU cache, avoiding mainline memory altogether.

Likewise, a mutable container like IORef or STRef both contain a pointer rather than the value. Use URef for an unboxed version.

Are you using Text or ByteString instead of String?

The String type is slow for these reasons:

  • It's a linked list, meaning access is linear.
  • It's not a packed representation, so each character is a separate structure with a pointer to the next. It requires access to mainline memory.
  • It allocates a lot more memory than packed representations.

Resources on string types:

Case studies:

Have you considered compiling with LLVM?

https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/codegens.html#llvm-code-generator-fllvm

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].