Need help with fast-crystal?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

icyleaf
149 Stars 7 Forks MIT License 46 Commits 2 Opened issues

Description

💨 Writing Fast Crystal 😍 -- Collect Common Crystal idioms.

Services available

!
?

Need anything else?

Contributors list

# 112,265
Crystal
MySQL
egpu
Ruby
28 commits
# 89,204
Discord
Crystal
gtk
wlroots
6 commits
# 41,339
Heroku
Crystal
ace
reactjs
1 commit
# 44,835
Rails
xslt
Bash
wip
1 commit

💎 Fast Crystal

It's Crystal version based on ruby version.

Each idiom has a corresponding code example that resides in code.

All results listed in README.md are running with Crystal 0.25.0 (2018-06-15) LLVM 5.0.1 on OS X 10.13.5.

Machine information: MacBook Pro (Retina, 15-inch, Mid 2015), 2.2 GHz Intel Core i7, 16 GB 1600 MHz DDR3.

Your results may vary, but you get the idea. : )

Doubt the results? please discuss in Crystal Issue#4383.

Let's write faster code, together! :trollface:

Measurement Tool

Use Crystal's built-in benchmark.

Run the Benchmarks

$ make

Template

require "benchmark"

def fast end

def slow end

Benchmark.ips do |x| x.report("fast code description") { fast } x.report("slow code description") { slow } end

Idioms

Index

Test in Crystal 0.35.1 (2020-06-19) LLVM: 10.0.0 Default target: x86_64-apple-macosx

Array

first
vs
index[0]
code

$ crystal build --release --no-debug -o bin/code/array/first-vs-index[0] code/array/first-vs-index[0].cr
$ ./bin/code/array/first-vs-index[0]

Array#first 265.31M ( 3.77ns) (±11.17%) 0.0B/op 1.01× slower Array#[0] 267.85M ( 3.73ns) (± 6.86%) 0.0B/op fastest

insert
vs
unshift
code

$ crystal build --release --no-debug -o bin/code/array/insert-vs-unshift code/array/insert-vs-unshift.cr
$ ./bin/code/array/insert-vs-unshift

Array#insert 1.30 (768.66ms) (± 1.33%) 1.5MB/op fastest Array#unshift 1.29 (775.05ms) (± 1.81%) 1.5MB/op 1.01× slower

last
vs
index[-1]
code

$ crystal build --release --no-debug -o bin/code/array/last-vs-index[-1] code/array/last-vs-index[-1].cr
$ ./bin/code/array/last-vs-index[-1]

Array#[-1] 273.97M ( 3.65ns) (± 4.16%) 0.0B/op fastest Array#last 273.61M ( 3.65ns) (± 4.75%) 0.0B/op 1.00× slower

range
vs
times.map
code

$ crystal build --release --no-debug -o bin/code/array/range-vs-times.map code/array/range-vs-times.map.cr
$ ./bin/code/array/range-vs-times.map

Range#to_a 1.11M (897.91ns) (±17.84%) 1.67kB/op fastest Times#to_a 1.02M (980.17ns) (±17.56%) 1.69kB/op 1.09× slower

Enumerable

each push
vs
map
code

$ crystal build --release --no-debug -o bin/code/enumerable/each-push-vs-map code/enumerable/each-push-vs-map.cr
$ ./bin/code/enumerable/each-push-vs-map

         Array#map 507.91k (  1.97µs) (±11.92%)  3.96kB/op        fastest
 Array#each + push 145.04k (  6.89µs) (±18.89%)  12.7kB/op   3.50× slower

Array#each_with_object 155.85k ( 6.42µs) (±17.07%) 12.7kB/op 3.26× slower

each
vs
loop
code

$ crystal build --release --no-debug -o bin/code/enumerable/each-vs-loop code/enumerable/each-vs-loop.cr
$ ./bin/code/enumerable/each-vs-loop

While Loop 1.64M (609.64ns) (± 7.66%) 0.0B/op 159.20× slower #each 261.15M ( 3.83ns) (±10.82%) 0.0B/op fastest

each_with_index
vs
while loop
code

$ crystal build --release --no-debug -o bin/code/enumerable/each_with_index-vs-while-loop code/enumerable/each_with_index-vs-while-loop.cr
$ ./bin/code/enumerable/each_with_index-vs-while-loop

 While Loop   1.51M (661.13ns) (± 9.29%)  0.0B/op   6.94× slower

each_with_index 10.50M ( 95.23ns) (±17.95%) 0.0B/op fastest

map flatten
vs
flat_map
code

$ crystal build --release --no-debug -o bin/code/enumerable/map-flatten-vs-flat_map code/enumerable/map-flatten-vs-flat_map.cr
$ ./bin/code/enumerable/map-flatten-vs-flat_map

Array#flat_map (Tuple) 902.86k ( 1.11µs) (± 6.63%) 3.65kB/op fastest Array#map.flatten (Tuple) 664.00k ( 1.51µs) (± 6.00%) 4.69kB/op 1.36× slower Array#flat_map (Array) 238.37k ( 4.20µs) (± 5.73%) 7.18kB/op 3.79× slower Array#map.flatten (Array) 193.64k ( 5.16µs) (± 3.78%) 9.39kB/op 4.66× slower

reverse.each
vs
reverse_each
code

$ crystal build --release --no-debug -o bin/code/enumerable/reverse.each-vs-reverse_each code/enumerable/reverse.each-vs-reverse_each.cr
$ ./bin/code/enumerable/reverse.each-vs-reverse_each

Array#reverse.each 4.03M (248.39ns) (± 5.02%) 480B/op 4.94× slower Array#reverse_each 19.88M ( 50.30ns) (± 2.49%) 0.0B/op fastest

sort
vs
sort_by
code

$ crystal build --release --no-debug -o bin/code/enumerable/sort-vs-sort_by code/enumerable/sort-vs-sort_by.cr
$ ./bin/code/enumerable/sort-vs-sort_by

Enumerable#sort 145.32k ( 6.88µs) (± 2.89%) 3.07kB/op 1.17× slower Enumerable#sort_by 170.71k ( 5.86µs) (± 4.47%) 1.04kB/op fastest

General

Assignment code

$ crystal build --release --no-debug -o bin/code/general/assignment code/general/assignment.cr
$ ./bin/code/general/assignment

Sequential Assignment 611.21M ( 1.64ns) (± 4.98%) 0.0B/op 1.00× slower Parallel Assignment 613.61M ( 1.63ns) (± 5.04%) 0.0B/op fastest

hash
vs
struct
vs
namedtuple
code

$ crystal build --release --no-debug -o bin/code/general/hash-vs-struct-vs-namedtuple code/general/hash-vs-struct-vs-namedtuple.cr
$ ./bin/code/general/hash-vs-struct-vs-namedtuple

NamedTuple 515.36M ( 1.94ns) (± 4.05%) 0.0B/op fastest Struct 503.85M ( 1.98ns) (± 6.54%) 0.0B/op 1.02× slower Hash 9.60M (104.18ns) (± 2.76%) 208B/op 53.69× slower

loop
vs
while_true
code

$ crystal build --release --no-debug -o bin/code/general/loop-vs-while_true code/general/loop-vs-while_true.cr
$ ./bin/code/general/loop-vs-while_true

While Loop 512.11M ( 1.95ns) (± 5.15%) 0.0B/op fastest Kernel Loop 482.98M ( 2.07ns) (±16.94%) 0.0B/op 1.06× slower

positional_argument
vs
named_argument
code

$ crystal build --release --no-debug -o bin/code/general/positional_argument-vs-named_argument code/general/positional_argument-vs-named_argument.cr
$ ./bin/code/general/positional_argument-vs-named_argument

 Named arguments 564.18M (  1.77ns) (±16.11%)  0.0B/op   1.03× slower

Positional arguments 578.90M ( 1.73ns) (±10.46%) 0.0B/op fastest

property
vs
getter_and_setter
code

$ crystal build --release --no-debug -o bin/code/general/property-vs-getter_and_setter code/general/property-vs-getter_and_setter.cr
$ ./bin/code/general/property-vs-getter_and_setter

     property  50.89M ( 19.65ns) (± 5.34%)  32.0B/op        fastest

getter_and_setter 49.68M ( 20.13ns) (± 7.27%) 32.0B/op 1.02× slower

Hash

[]?
vs
has_key?
code

$ crystal build --release --no-debug -o bin/code/hash/[]?-vs-has_key? code/hash/[]?-vs-has_key?.cr
$ ./bin/code/hash/[]?-vs-has_key?

 Hash#[]?  41.12M ( 24.32ns) (±12.09%)  0.0B/op   1.01× slower

Hash#has_key? 41.48M ( 24.11ns) (± 8.25%) 0.0B/op fastest

bracket
vs
fetch
code

$ crystal build --release --no-debug -o bin/code/hash/bracket-vs-fetch code/hash/bracket-vs-fetch.cr
$ ./bin/code/hash/bracket-vs-fetch

Hash#[] 95.60M ( 10.46ns) (± 6.16%) 0.0B/op 1.02× slower Hash#fetch 97.08M ( 10.30ns) (± 9.36%) 0.0B/op fastest

clone
vs
dup
code

$ crystal build --release --no-debug -o bin/code/hash/clone-vs-dup code/hash/clone-vs-dup.cr
$ ./bin/code/hash/clone-vs-dup

Hash#dup 5.39M (185.50ns) (±17.96%) 480B/op fastest Hash#clone 293.35k ( 3.41µs) (±10.17%) 5.94kB/op 18.38× slower

keys each
vs
each_key
code

$ crystal build --release --no-debug -o bin/code/hash/keys-each-vs-each_key code/hash/keys-each-vs-each_key.cr
$ ./bin/code/hash/keys-each-vs-each_key

Hash#keys.each 4.25M (235.11ns) (± 8.09%) 240B/op 1.11× slower Hash#each_key 4.71M (212.43ns) (±22.16%) 160B/op fastest

merge bang
vs
[]=
code

$ crystal build --release --no-debug -o bin/code/hash/merge-bang-vs-[]= code/hash/merge-bang-vs-[]=.cr
$ ./bin/code/hash/merge-bang-vs-[]=

Hash#merge! 67.40k ( 14.84µs) (±23.77%) 16.6kB/op 4.19× slower Hash#[]= 282.73k ( 3.54µs) (±21.37%) 4.14kB/op fastest

Namedtuple

bracket
vs
fetch
code

$ crystal build --release --no-debug -o bin/code/namedtuple/bracket-vs-fetch code/namedtuple/bracket-vs-fetch.cr
$ ./bin/code/namedtuple/bracket-vs-fetch

NamedTuple#[] 294.37M ( 3.40ns) (±19.52%) 0.0B/op 1.00× slower NamedTuple#fetch 295.49M ( 3.38ns) (±19.80%) 0.0B/op fastest

fetch
vs
fetch_with_block
code

$ crystal build --release --no-debug -o bin/code/namedtuple/fetch-vs-fetch_with_block code/namedtuple/fetch-vs-fetch_with_block.cr
$ ./bin/code/namedtuple/fetch-vs-fetch_with_block

NamedTuple#fetch + const 168.24M ( 5.94ns) (± 6.53%) 0.0B/op 1.81× slower NamedTuple#fetch + block 304.53M ( 3.28ns) (± 4.50%) 0.0B/op fastest NamedTuple#fetch + arg 296.07M ( 3.38ns) (± 6.99%) 0.0B/op 1.03× slower

Proc & Block

block
vs
to_proc
code

$ crystal build --release --no-debug -o bin/code/proc-and-block/block-vs-to_proc code/proc-and-block/block-vs-to_proc.cr
$ ./bin/code/proc-and-block/block-vs-to_proc

     Block 331.06k (  3.02µs) (±13.18%)  2.6kB/op   1.10× slower

Symbol#to_proc 362.78k ( 2.76µs) (± 5.27%) 2.6kB/op fastest

proc call
vs
yield
code

$ crystal build --release --no-debug -o bin/code/proc-and-block/proc-call-vs-yield code/proc-and-block/proc-call-vs-yield.cr
$ ./bin/code/proc-and-block/proc-call-vs-yield

block.call 513.72M (  1.95ns) (± 4.51%)  0.0B/op        fastest

block + yield 501.67M ( 1.99ns) (± 7.25%) 0.0B/op 1.02× slower block argument 512.94M ( 1.95ns) (± 5.41%) 0.0B/op 1.00× slower yield 482.96M ( 2.07ns) (±15.43%) 0.0B/op 1.06× slower

String

Concatenation code

$ crystal build --release --no-debug -o bin/code/string/concatenation code/string/concatenation.cr
$ ./bin/code/string/concatenation

String#+ 44.62M ( 22.41ns) (± 8.00%) 32.0B/op fastest String#{} 23.68M ( 42.22ns) (±16.74%) 32.0B/op 1.88× slower String#% 4.28M (233.43ns) (±20.03%) 176B/op 10.41× slower

ends string-matching-match
vs
end_with
code

$ crystal build --release --no-debug -o bin/code/string/ends-string-matching-match-vs-end_with code/string/ends-string-matching-match-vs-end_with.cr
$ ./bin/code/string/ends-string-matching-match-vs-end_with

String#end_with? 238.71M ( 4.19ns) (±11.61%) 0.0B/op fastest String#=~ 7.93M (126.04ns) (± 4.61%) 16.0B/op 30.09× slower

Equal-substring-of-char code

$ crystal build --release --no-debug -o bin/code/string/equal-substring-of-char code/string/equal-substring-of-char.cr
$ ./bin/code/string/equal-substring-of-char

     "==="[0] == '=' 298.29M (  3.35ns) (± 7.06%)   0.0B/op        fastest
"==="[0].to_s == "="  23.29M ( 42.94ns) (± 6.52%)  48.0B/op  12.81× slower

"==="[0] == "=".chars[0] 27.62M ( 36.21ns) (± 4.66%) 48.0B/op 10.80× slower

equal
vs
match
code

$ crystal build --release --no-debug -o bin/code/string/equal-vs-match code/string/equal-vs-match.cr
$ ./bin/code/string/equal-vs-match

String#match 15.00M ( 66.65ns) (± 8.74%) 16.0B/op 1.02× slower Regexp#=== 15.32M ( 65.27ns) (± 9.61%) 16.0B/op fastest String#=~ 14.67M ( 68.17ns) (± 8.60%) 16.0B/op 1.04× slower

gsub
vs
sub
code

$ crystal build --release --no-debug -o bin/code/string/gsub-vs-sub code/string/gsub-vs-sub.cr
$ ./bin/code/string/gsub-vs-sub

String#sub 3.67M (272.77ns) (± 5.43%) 1.22kB/op fastest String#gsub 1.37M (728.87ns) (± 4.13%) 1.22kB/op 2.67× slower

includes
vs
to_s.includes
code

$ crystal build --release --no-debug -o bin/code/string/includes-vs-to_s.includes code/string/includes-vs-to_s.includes.cr
$ ./bin/code/string/includes-vs-to_s.includes

String#includes? 368.22M ( 2.72ns) (± 8.30%) 0.0B/op 1.02× slower Nil#to_s#includes? 376.21M ( 2.66ns) (± 6.76%) 0.0B/op fastest

nil
vs
to_s.empty
code

$ crystal build --release --no-debug -o bin/code/string/nil-vs-to_s.empty code/string/nil-vs-to_s.empty.cr
$ ./bin/code/string/nil-vs-to_s.empty

String#nil? 468.25M (  2.14ns) (±14.49%)  0.0B/op        fastest

Nil#to_s#empty? 450.24M ( 2.22ns) (±14.74%) 0.0B/op 1.04× slower

sub
vs
chomp
code

$ crystal build --release --no-debug -o bin/code/string/sub-vs-chomp code/string/sub-vs-chomp.cr
$ ./bin/code/string/sub-vs-chomp

String#chomp"string" 43.85M ( 22.81ns) (±12.35%) 32.0B/op fastest String#sub/regexp/ 3.57M (280.13ns) (± 5.92%) 176B/op 12.28× slower

You may also like

  • halite - HTTP Requests Client with a chainable REST API, built-in sessions and middlewares.
  • totem - Load and parse a configuration file or string in JSON, YAML, dotenv formats.
  • markd - Yet another markdown parser built for speed, Compliant to CommonMark specification.
  • poncho - A .env parser/loader improved for performance.
  • popcorn - Easy and Safe casting from one type to another.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.