Full Code of icyleaf/fast-crystal for AI

master da672edb3b67 cached
38 files
27.6 KB
11.2k tokens
1 requests
Download .txt
Repository: icyleaf/fast-crystal
Branch: master
Commit: da672edb3b67
Files: 38
Total size: 27.6 KB

Directory structure:
gitextract_y1nbnp85/

├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── code/
│   ├── array/
│   │   ├── first-vs-index[0].cr
│   │   ├── insert-vs-unshift.cr
│   │   ├── last-vs-index[-1].cr
│   │   └── range-vs-times.map.cr
│   ├── enumerable/
│   │   ├── each-push-vs-map.cr
│   │   ├── each-vs-loop.cr
│   │   ├── each_with_index-vs-while-loop.cr
│   │   ├── map-flatten-vs-flat_map.cr
│   │   ├── reverse.each-vs-reverse_each.cr
│   │   └── sort-vs-sort_by.cr
│   ├── general/
│   │   ├── assignment.cr
│   │   ├── hash-vs-struct-vs-namedtuple.cr
│   │   ├── loop-vs-while_true.cr
│   │   ├── positional_argument-vs-named_argument.cr
│   │   └── property-vs-getter_and_setter.cr
│   ├── hash/
│   │   ├── []?-vs-has_key?.cr
│   │   ├── bracket-vs-fetch.cr
│   │   ├── clone-vs-dup.cr
│   │   ├── keys-each-vs-each_key.cr
│   │   └── merge-bang-vs-[]=.cr
│   ├── namedtuple/
│   │   ├── bracket-vs-fetch.cr
│   │   └── fetch-vs-fetch_with_block.cr
│   ├── proc-and-block/
│   │   ├── block-vs-to_proc.cr
│   │   └── proc-call-vs-yield.cr
│   └── string/
│       ├── concatenation.cr
│       ├── ends-string-matching-match-vs-end_with.cr
│       ├── equal-substring-of-char.cr
│       ├── equal-vs-match.cr
│       ├── gsub-vs-sub.cr
│       ├── includes-vs-to_s.includes.cr
│       ├── nil-vs-to_s.empty.cr
│       └── sub-vs-chomp.cr
├── shard.yml
└── src/
    └── fast-crystal.cr

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
/doc/
/lib/
/bin/
/.shards/


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2017-2019 icyleaf

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


================================================
FILE: Makefile
================================================
CRYSTAL_BIN ?= $(shell which crystal)
PREFIX ?= /usr/local

run: build
	./bin/fast-crystal

clean:
	rm -rf bin
	mkdir bin

build: clean
	$(CRYSTAL_BIN) build --release --no-debug -o bin/fast-crystal src/fast-crystal.cr $(CRFLAGS)


================================================
FILE: README.md
================================================
# 💎 Fast Crystal

It's Crystal version based on [ruby version](https://github.com/JuanitoFatas/fast-ruby).

Each idiom has a corresponding code example that resides in [code](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](https://github.com/crystal-lang/crystal/issues/4383).

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

## Measurement Tool

Use Crystal's built-in [benchmark](https://crystal-lang.org/api/0.22.0/Benchmark.html).

## Run the Benchmarks

```bash
$ make
```

### Template

```crystal
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

- [Array](#array)
- [Enumerable](#enumerable)
- [General](#general)
- [Hash](#hash)
- [NamedTuple](#namedtuple)
- [Proc & Block](#proc--block)
- [String](#string)

> 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](code/array/first-vs-index[0].cr)

```
$ 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](code/array/insert-vs-unshift.cr)

```
$ 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](code/array/last-vs-index[-1].cr)

```
$ 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](code/array/range-vs-times.map.cr)

```
$ 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](code/enumerable/each-push-vs-map.cr)

```
$ 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](code/enumerable/each-vs-loop.cr)

```
$ 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](code/enumerable/each_with_index-vs-while-loop.cr)

```
$ 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](code/enumerable/map-flatten-vs-flat_map.cr)

```
$ 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](code/enumerable/reverse.each-vs-reverse_each.cr)

```
$ 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](code/enumerable/sort-vs-sort_by.cr)

```
$ 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](code/general/assignment.cr)

```
$ 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](code/general/hash-vs-struct-vs-namedtuple.cr)

```
$ 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](code/general/loop-vs-while_true.cr)

```
$ 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](code/general/positional_argument-vs-named_argument.cr)

```
$ 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](code/general/property-vs-getter_and_setter.cr)

```
$ 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](code/hash/[]?-vs-has_key?.cr)

```
$ 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](code/hash/bracket-vs-fetch.cr)

```
$ 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](code/hash/clone-vs-dup.cr)

```
$ 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](code/hash/keys-each-vs-each_key.cr)

```
$ 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](code/hash/merge-bang-vs-[]=.cr)

```
$ 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](code/namedtuple/bracket-vs-fetch.cr)

```
$ 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](code/namedtuple/fetch-vs-fetch_with_block.cr)

```
$ 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](code/proc-and-block/block-vs-to_proc.cr)

```
$ 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](code/proc-and-block/proc-call-vs-yield.cr)

```
$ 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](code/string/concatenation.cr)

```
$ 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](code/string/ends-string-matching-match-vs-end_with.cr)

```
$ 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](code/string/equal-substring-of-char.cr)

```
$ 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](code/string/equal-vs-match.cr)

```
$ 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](code/string/gsub-vs-sub.cr)

```
$ 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](code/string/includes-vs-to_s.includes.cr)

```
$ 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](code/string/nil-vs-to_s.empty.cr)

```
$ 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](code/string/sub-vs-chomp.cr)

```
$ 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](https://github.com/icyleaf/halite) - HTTP Requests Client with a chainable REST API, built-in sessions and middlewares.
- [totem](https://github.com/icyleaf/totem) - Load and parse a configuration file or string in JSON, YAML, dotenv formats.
- [markd](https://github.com/icyleaf/markd) - Yet another markdown parser built for speed, Compliant to CommonMark specification.
- [poncho](https://github.com/icyleaf/poncho) - A .env parser/loader improved for performance.
- [popcorn](https://github.com/icyleaf/popcorn) - Easy and Safe casting from one type to another.


================================================
FILE: code/array/first-vs-index[0].cr
================================================
require "benchmark"

ARRAY = (1..100).to_a

def fast
  ARRAY.first
end

def slow
  ARRAY[0]
end

Benchmark.ips do |x|
  x.report("Array#first") { fast }
  x.report("Array#[0]") { slow }
end


================================================
FILE: code/array/insert-vs-unshift.cr
================================================
require "benchmark"

Benchmark.ips do |x|
  x.report("Array#insert") do
    array = [] of Int32
    100_000.times { |i| array.insert(0, i) }
  end

  x.report("Array#unshift") do
    array = [] of Int32
    100_000.times { |i| array.unshift(i) }
  end
end


================================================
FILE: code/array/last-vs-index[-1].cr
================================================
require "benchmark"

ARRAY = (1..100).to_a

def fast
  ARRAY[-1]
end

def slow
  ARRAY.last
end

Benchmark.ips do |x|
  x.report("Array#[-1]") { fast }
  x.report("Array#last") { slow }
end


================================================
FILE: code/array/range-vs-times.map.cr
================================================
require "benchmark"

Benchmark.ips do |x|
  x.report("Range#to_a") do
    (1..100).to_a
  end

  x.report("Times#to_a") do
    100.times.map { |i| i + 1 }.to_a
  end
end


================================================
FILE: code/enumerable/each-push-vs-map.cr
================================================
require "benchmark"

ARRAY = (1..1000).to_a

def fastest
  ARRAY.map { |i| i }
end

def fast
  array = [] of Int32
  ARRAY.each { |i| array.push i }
  array
end

def slow
  ARRAY.each_with_object([] of Int32) { |i, obj| obj << i }
end

Benchmark.ips do |x|
  x.report("Array#map") { fastest }
  x.report("Array#each + push") { fast }
  x.report("Array#each_with_object") { slow }
end


================================================
FILE: code/enumerable/each-vs-loop.cr
================================================
require "benchmark"

ARRAY = (1..100).to_a

def fast
  i = 0
  while i < ARRAY.size
    ARRAY[i]
    i += 1
  end
end

def slow
  ARRAY.each do |number|
    number
  end
end

Benchmark.ips do |x|
  x.report("While Loop") { fast }
  x.report("#each") { slow }
end


================================================
FILE: code/enumerable/each_with_index-vs-while-loop.cr
================================================
require "benchmark"

ARRAY = (1..100).to_a

def fast
  index = 0
  while index < ARRAY.size
    ARRAY[index] + index
    index += 1
  end
  ARRAY
end

def slow
  ARRAY.each_with_index do |number, index|
    number + index
  end
end

Benchmark.ips do |x|
  x.report("While Loop") { fast }
  x.report("each_with_index") { slow }
end


================================================
FILE: code/enumerable/map-flatten-vs-flat_map.cr
================================================
require "benchmark"

ARRAY = (1..100).to_a

def fastest
  ARRAY.flat_map { |e| {e, e} }
end

def fast
  ARRAY.map { |e| {e, e} }.flatten
end

def slow
  ARRAY.flat_map { |e| [e, e] }
end

def slowest
  ARRAY.map { |e| [e, e] }.flatten
end

Benchmark.ips do |x|
  x.report("Array#flat_map (Tuple)") { fastest }
  x.report("Array#map.flatten (Tuple)") { fast }
  x.report("Array#flat_map (Array)") { slow }
  x.report("Array#map.flatten (Array)") { slowest }
end


================================================
FILE: code/enumerable/reverse.each-vs-reverse_each.cr
================================================
require "benchmark"

ARRAY = (1..100).to_a

def slow
  ARRAY.reverse.each { |x| x }
end

def fast
  ARRAY.reverse_each { |x| x }
end

Benchmark.ips do |x|
  x.report("Array#reverse.each") { slow }
  x.report("Array#reverse_each") { fast }
end


================================================
FILE: code/enumerable/sort-vs-sort_by.cr
================================================
require "benchmark"

struct User
  property name

  def initialize(@name : String)
  end
end

ARRAY = Array.new(100) do
  User.new(sprintf "%010d", rand(1_000_000_000))
end

def fast
  ARRAY.sort_by(&.name)
end

def slow
  ARRAY.sort { |a, b| a.name <=> b.name }
end

Benchmark.ips do |x|
  x.report("Enumerable#sort") { fast }
  x.report("Enumerable#sort_by") { slow }
end


================================================
FILE: code/general/assignment.cr
================================================
require "benchmark"

def fast
  _a, _b, _c, _d, _e, _f, _g, _h = 1, 2, 3, 4, 5, 6, 7, 8
  nil
end

def slow
  _a = 1
  _b = 2
  _c = 3
  _d = 4
  _e = 5
  _f = 6
  _g = 7
  _h = 8
  nil
end

Benchmark.ips do |x|
  x.report("Sequential Assignment") { slow }
  x.report("Parallel Assignment") { fast }
end


================================================
FILE: code/general/hash-vs-struct-vs-namedtuple.cr
================================================
require "benchmark"

struct SampleStruct
  property name, year

  def initialize(@name : String, @year : Int32)
  end
end

def slow
  {"name" => "Crystal", "year" => 2011}
end

def fast
  SampleStruct.new("Crystal", 2011)
end

def fastest
  {name: "Crystal", year: 2011}
end

Benchmark.ips do |x|
  x.report("NamedTuple") { fastest }
  x.report("Struct") { fast }
  x.report("Hash") { slow }
end


================================================
FILE: code/general/loop-vs-while_true.cr
================================================
require "benchmark"

NUMBER = 100_000_000

def fast
  index = 0
  while true
    break if index > NUMBER
    index += 1
  end
end

def slow
  index = 0
  loop do
    break if index > NUMBER
    index += 1
  end
end

Benchmark.ips do |x|
  x.report("While Loop") { fast }
  x.report("Kernel Loop") { slow }
end


================================================
FILE: code/general/positional_argument-vs-named_argument.cr
================================================
require "benchmark"

module M
  def self.func(a, b, c)
  end
end

def fast
  M.func(a: 1, b: 2, c: 3)
end

def slow
  M.func(1, 2, 3)
end

Benchmark.ips do |x|
  x.report("Named arguments") { fast }
  x.report("Positional arguments") { slow }
end


================================================
FILE: code/general/property-vs-getter_and_setter.cr
================================================
require "benchmark"

class User
  property :first_name

  def initialize
    @first_name = ""
    @last_name = ""
  end

  def last_name
    @last_name
  end

  def last_name=(value)
    @last_name = value
  end
end

def slow
  user = User.new
  user.last_name = "Wang"
  user.last_name
end

def fast
  user = User.new
  user.first_name = "Wang"
  user.first_name
end

Benchmark.ips do |x|
  x.report("property") { fast }
  x.report("getter_and_setter") { slow }
end


================================================
FILE: code/hash/[]?-vs-has_key?.cr
================================================
require "benchmark"

HASH = {"a" => "z"}

Benchmark.ips do |x|
  x.report("Hash#[]?") do
    HASH["a"]?
    HASH["b"]?
  end

  x.report("Hash#has_key?") do
    HASH.has_key? "a"
    HASH.has_key? "b"
  end
end


================================================
FILE: code/hash/bracket-vs-fetch.cr
================================================
require "benchmark"

HASH       = {"fast" => "ruby"}
NAMEDTUPLE = {fast: "ruby"}

Benchmark.ips do |x|
  x.report("Hash#[]") do
    HASH["fast"]
  end

  x.report("Hash#fetch") do
    HASH.fetch("fast") { }
  end
end


================================================
FILE: code/hash/clone-vs-dup.cr
================================================
require "benchmark"

HASH = ("a".."z").map { |v| {v => v.bytes} }

def fast
  HASH.dup
end

def slow
  HASH.clone
end

Benchmark.ips do |x|
  x.report("Hash#dup") { fast }
  x.report("Hash#clone") { slow }
end


================================================
FILE: code/hash/keys-each-vs-each_key.cr
================================================
require "benchmark"

HASH = {
  "provider" => "facebook",
  "uid"      => "1234567",
  "info"     => {
    "nickname"   => "jbloggs",
    "email"      => "joe@bloggs.com",
    "name"       => "Joe Bloggs",
    "first_name" => "Joe",
    "last_name"  => "Bloggs",
    "image"      => "http://graph.facebook.com/1234567/picture?type=square",
    "urls"       => {"Facebook" => "http://www.facebook.com/jbloggs"},
    "location"   => "Palo Alto, California",
    "verified"   => true,
  },
  "credentials" => {
    "token"      => "ABCDEF...",
    "expires_at" => 1321747205,
    "expires"    => true,
  },
  "extra" => {
    "raw_info" => {
      "id"           => "1234567",
      "name"         => "Joe Bloggs",
      "first_name"   => "Joe",
      "last_name"    => "Bloggs",
      "link"         => "http://www.facebook.com/jbloggs",
      "username"     => "jbloggs",
      "location"     => {"id" => "123456789", "name" => "Palo Alto, California"},
      "gender"       => "male",
      "email"        => "joe@bloggs.com",
      "timezone"     => -8,
      "locale"       => "en_US",
      "verified"     => true,
      "updated_time" => "2011-11-11T06:21:03+0000",
    },
  },
}

def slow
  HASH.keys.each(&.downcase)
end

def fast
  HASH.each_key(&.downcase)
end

Benchmark.ips do |x|
  x.report("Hash#keys.each") { slow }
  x.report("Hash#each_key") { fast }
end


================================================
FILE: code/hash/merge-bang-vs-[]=.cr
================================================
require "benchmark"

ENUM = (1..100)

def slow
  ENUM.each_with_object({} of Int32 => Int32) do |e, h|
    h.merge!({e => e})
  end
end

def fast
  ENUM.each_with_object({} of Int32 => Int32) do |e, h|
    h[e] = e
  end
end

Benchmark.ips do |x|
  x.report("Hash#merge!") { slow }
  x.report("Hash#[]=") { fast }
end


================================================
FILE: code/namedtuple/bracket-vs-fetch.cr
================================================
require "benchmark"

NAMEDTUPLE = {fast: "ruby"}

def fast
  NAMEDTUPLE[:fast]
end

def slow
  NAMEDTUPLE.fetch(:fast, "")
end

Benchmark.ips do |x|
  x.report("NamedTuple#[]") { fast }
  x.report("NamedTuple#fetch") { slow }
end


================================================
FILE: code/namedtuple/fetch-vs-fetch_with_block.cr
================================================
require "benchmark"

HASH    = {writing: :fast_ruby}
DEFAULT = "fast ruby"

Benchmark.ips do |x|
  x.report("NamedTuple#fetch + const") { HASH.fetch(:writing, DEFAULT) }
  x.report("NamedTuple#fetch + block") { HASH.fetch(:writing) { "fast ruby" } }
  x.report("NamedTuple#fetch + arg") { HASH.fetch(:writing, "fast ruby") }
end


================================================
FILE: code/proc-and-block/block-vs-to_proc.cr
================================================
require "benchmark"

RANGE = (1..100)

def slow
  RANGE.map { |i| i.to_s }
end

def fast
  RANGE.map(&.to_s)
end

Benchmark.ips do |x|
  x.report("Block") { slow }
  x.report("Symbol#to_proc") { fast }
end


================================================
FILE: code/proc-and-block/proc-call-vs-yield.cr
================================================
require "benchmark"

def slow(&block)
  block.call
end

def slow2(&block)
  yield
end

def slow3(&block)
end

def fast
  yield
end

Benchmark.ips do |x|
  x.report("block.call") { slow { 1 + 1 } }
  x.report("block + yield") { slow2 { 1 + 1 } }
  x.report("block argument") { slow3 { 1 + 1 } }
  x.report("yield") { fast { 1 + 1 } }
end


================================================
FILE: code/string/concatenation.cr
================================================
require "benchmark"

WORLD = "world"

def fastest
  "hello " + WORLD
end

def fast
  "hello #{WORLD}"
end

def slow
  "hello %s" % WORLD
end

Benchmark.ips do |x|
  x.report("String#+") { fastest }
  x.report("String\#{}") { fast }
  x.report("String#%") { slow }
end


================================================
FILE: code/string/ends-string-matching-match-vs-end_with.cr
================================================
require "benchmark"

SLUG = "root_url"

def fast
  SLUG.ends_with?("_url")
end

def slow
  SLUG =~ /_url$/
end

Benchmark.ips do |x|
  x.report("String#end_with?") { fast }
  x.report("String#=~") { slow }
end


================================================
FILE: code/string/equal-substring-of-char.cr
================================================
require "benchmark"

def fastest
  "===="[0] == '='
end

def fast
  "===="[0].to_s == "="
end

def slow
  "===="[0] == "=".chars[0]
end

Benchmark.ips do |x|
  x.report("\"===\"[0] == '='") { fastest }
  x.report("\"===\"[0].to_s == \"=\"") { fast }
  x.report("\"===\"[0] == \"=\".chars[0]") { slow }
end


================================================
FILE: code/string/equal-vs-match.cr
================================================
require "benchmark"

def fastest
  "foo".match(/boo/)
end

def fast
  /boo/ === "foo"
end

def slow
  "foo" =~ /boo/
end

Benchmark.ips do |x|
  x.report("String#match") { fastest }
  x.report("Regexp#===") { fast }
  x.report("String#=~") { slow }
end


================================================
FILE: code/string/gsub-vs-sub.cr
================================================
require "benchmark"

URL = "http://www.thelongestlistofthelongeststuffatthelongestdomainnameatlonglast.com/wearejustdoingthistobestupidnowsincethiscangoonforeverandeverandeverbutitstilllookskindaneatinthebrowsereventhoughitsabigwasteoftimeandenergyandhasnorealpointbutwehadtodoitanyways.html"

def slow
  URL.gsub("http://", "https://")
end

def fast
  URL.sub("http://", "https://")
end

Benchmark.ips do |x|
  x.report("String#sub") { fast }
  x.report("String#gsub") { slow }
end


================================================
FILE: code/string/includes-vs-to_s.includes.cr
================================================
require "benchmark"

def slow
  "foobar".includes?("crystal")
end

def fast
  nil.to_s.includes?("crystal")
end

Benchmark.ips do |x|
  x.report("String#includes?") { fast }
  x.report("Nil#to_s#includes?") { slow }
end


================================================
FILE: code/string/nil-vs-to_s.empty.cr
================================================
require "benchmark"

def slow
  nil.to_s.empty?
end

def fast
  "".nil?
end

Benchmark.ips do |x|
  x.report("String#nil?") { fast }
  x.report("Nil#to_s#empty?") { slow }
end


================================================
FILE: code/string/sub-vs-chomp.cr
================================================
require "benchmark"

SLUG = "YourSubclassType"

def fast
  SLUG.chomp("Type")
end

def slow
  SLUG.sub(/Type\z/, "")
end

Benchmark.ips do |x|
  x.report("String#chomp\"string\"") { fast }
  x.report("String#sub/regexp/") { slow }
end


================================================
FILE: shard.yml
================================================
name: fast-crystal
version: 0.2.2

authors:
  - icyleaf <icyleaf.cn@gmail.com>

targets:
  fast-crystal:
    main: src/fast-crystal.cr

crystal: 0.35.1

license: MIT


================================================
FILE: src/fast-crystal.cr
================================================
require "file_utils"

BIN_PATH        = "bin/code"
SOURCE_PATH     = File.expand_path("code")
CRYSTAL_BIN     = `which crystal`.strip
CRYSTAL_VERSION = `#{CRYSTAL_BIN} -v`.strip

if Dir.exists?(BIN_PATH)
  FileUtils.rm_rf(BIN_PATH)
end

puts
puts "> Test in #{CRYSTAL_VERSION.split("\n").join(" ")}"
puts

section = ""

files = if (file = ARGV[0]?) && File.exists? file
          {file}
        else
          Dir.glob("code/**/*.cr").sort
        end
files.each do |file|
  test_file = File.basename(file)
  test_section = file.sub(test_file, "").sub("code/", "")[0..-2]

  bin_section = File.join(BIN_PATH, test_section)
  bin_file = File.join(bin_section, File.basename(test_file, File.extname(test_file)))

  FileUtils.mkdir_p(bin_section)

  if section.empty? || section != test_section
    section = test_section
    puts "### " + (section == "proc-and-block" ? "Proc & Block" : section.capitalize)
    puts
  end

  compile_command = [CRYSTAL_BIN, "build", "--release", "--no-debug", "-o", bin_file, file]
  print_title(file)
  puts
  puts "```"
  puts "$ " + compile_command.join(" ")
  `#{compile_command.join(" ")}`

  puts "$ ./" + bin_file
  puts
  puts `./#{bin_file}`
  puts "```"
  puts
end

def print_title(file)
  filename = File.basename(file)
  file_path = file.sub(SOURCE_PATH, "")

  title = filename.sub(File.extname(filename), "")
  title = if title.includes?("-vs-")
            title_sections = [] of String
            title.split("-vs-").each do |str|
              title_sections << "`" + (str.includes?("[-1]") ? str : str.sub("-", " ")) + "`"
            end

            title_sections.join(" vs ")
          else
            title.capitalize
          end

  puts "#### " + title + " [code](" + file_path + ")"
end
Download .txt
gitextract_y1nbnp85/

├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── code/
│   ├── array/
│   │   ├── first-vs-index[0].cr
│   │   ├── insert-vs-unshift.cr
│   │   ├── last-vs-index[-1].cr
│   │   └── range-vs-times.map.cr
│   ├── enumerable/
│   │   ├── each-push-vs-map.cr
│   │   ├── each-vs-loop.cr
│   │   ├── each_with_index-vs-while-loop.cr
│   │   ├── map-flatten-vs-flat_map.cr
│   │   ├── reverse.each-vs-reverse_each.cr
│   │   └── sort-vs-sort_by.cr
│   ├── general/
│   │   ├── assignment.cr
│   │   ├── hash-vs-struct-vs-namedtuple.cr
│   │   ├── loop-vs-while_true.cr
│   │   ├── positional_argument-vs-named_argument.cr
│   │   └── property-vs-getter_and_setter.cr
│   ├── hash/
│   │   ├── []?-vs-has_key?.cr
│   │   ├── bracket-vs-fetch.cr
│   │   ├── clone-vs-dup.cr
│   │   ├── keys-each-vs-each_key.cr
│   │   └── merge-bang-vs-[]=.cr
│   ├── namedtuple/
│   │   ├── bracket-vs-fetch.cr
│   │   └── fetch-vs-fetch_with_block.cr
│   ├── proc-and-block/
│   │   ├── block-vs-to_proc.cr
│   │   └── proc-call-vs-yield.cr
│   └── string/
│       ├── concatenation.cr
│       ├── ends-string-matching-match-vs-end_with.cr
│       ├── equal-substring-of-char.cr
│       ├── equal-vs-match.cr
│       ├── gsub-vs-sub.cr
│       ├── includes-vs-to_s.includes.cr
│       ├── nil-vs-to_s.empty.cr
│       └── sub-vs-chomp.cr
├── shard.yml
└── src/
    └── fast-crystal.cr
Condensed preview — 38 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (32K chars).
[
  {
    "path": ".gitignore",
    "chars": 28,
    "preview": "/doc/\n/lib/\n/bin/\n/.shards/\n"
  },
  {
    "path": "LICENSE",
    "chars": 1079,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2017-2019 icyleaf\n\nPermission is hereby granted, free of charge, to any person obta"
  },
  {
    "path": "Makefile",
    "chars": 230,
    "preview": "CRYSTAL_BIN ?= $(shell which crystal)\nPREFIX ?= /usr/local\n\nrun: build\n\t./bin/fast-crystal\n\nclean:\n\trm -rf bin\n\tmkdir bi"
  },
  {
    "path": "README.md",
    "chars": 14833,
    "preview": "# 💎 Fast Crystal\n\nIt's Crystal version based on [ruby version](https://github.com/JuanitoFatas/fast-ruby).\n\nEach idiom h"
  },
  {
    "path": "code/array/first-vs-index[0].cr",
    "chars": 190,
    "preview": "require \"benchmark\"\n\nARRAY = (1..100).to_a\n\ndef fast\n  ARRAY.first\nend\n\ndef slow\n  ARRAY[0]\nend\n\nBenchmark.ips do |x|\n  "
  },
  {
    "path": "code/array/insert-vs-unshift.cr",
    "chars": 256,
    "preview": "require \"benchmark\"\n\nBenchmark.ips do |x|\n  x.report(\"Array#insert\") do\n    array = [] of Int32\n    100_000.times { |i| "
  },
  {
    "path": "code/array/last-vs-index[-1].cr",
    "chars": 190,
    "preview": "require \"benchmark\"\n\nARRAY = (1..100).to_a\n\ndef fast\n  ARRAY[-1]\nend\n\ndef slow\n  ARRAY.last\nend\n\nBenchmark.ips do |x|\n  "
  },
  {
    "path": "code/array/range-vs-times.map.cr",
    "chars": 170,
    "preview": "require \"benchmark\"\n\nBenchmark.ips do |x|\n  x.report(\"Range#to_a\") do\n    (1..100).to_a\n  end\n\n  x.report(\"Times#to_a\") "
  },
  {
    "path": "code/enumerable/each-push-vs-map.cr",
    "chars": 384,
    "preview": "require \"benchmark\"\n\nARRAY = (1..1000).to_a\n\ndef fastest\n  ARRAY.map { |i| i }\nend\n\ndef fast\n  array = [] of Int32\n  ARR"
  },
  {
    "path": "code/enumerable/each-vs-loop.cr",
    "chars": 263,
    "preview": "require \"benchmark\"\n\nARRAY = (1..100).to_a\n\ndef fast\n  i = 0\n  while i < ARRAY.size\n    ARRAY[i]\n    i += 1\n  end\nend\n\nd"
  },
  {
    "path": "code/enumerable/each_with_index-vs-while-loop.cr",
    "chars": 331,
    "preview": "require \"benchmark\"\n\nARRAY = (1..100).to_a\n\ndef fast\n  index = 0\n  while index < ARRAY.size\n    ARRAY[index] + index\n   "
  },
  {
    "path": "code/enumerable/map-flatten-vs-flat_map.cr",
    "chars": 461,
    "preview": "require \"benchmark\"\n\nARRAY = (1..100).to_a\n\ndef fastest\n  ARRAY.flat_map { |e| {e, e} }\nend\n\ndef fast\n  ARRAY.map { |e| "
  },
  {
    "path": "code/enumerable/reverse.each-vs-reverse_each.cr",
    "chars": 243,
    "preview": "require \"benchmark\"\n\nARRAY = (1..100).to_a\n\ndef slow\n  ARRAY.reverse.each { |x| x }\nend\n\ndef fast\n  ARRAY.reverse_each {"
  },
  {
    "path": "code/enumerable/sort-vs-sort_by.cr",
    "chars": 374,
    "preview": "require \"benchmark\"\n\nstruct User\n  property name\n\n  def initialize(@name : String)\n  end\nend\n\nARRAY = Array.new(100) do\n"
  },
  {
    "path": "code/general/assignment.cr",
    "chars": 304,
    "preview": "require \"benchmark\"\n\ndef fast\n  _a, _b, _c, _d, _e, _f, _g, _h = 1, 2, 3, 4, 5, 6, 7, 8\n  nil\nend\n\ndef slow\n  _a = 1\n  _"
  },
  {
    "path": "code/general/hash-vs-struct-vs-namedtuple.cr",
    "chars": 396,
    "preview": "require \"benchmark\"\n\nstruct SampleStruct\n  property name, year\n\n  def initialize(@name : String, @year : Int32)\n  end\nen"
  },
  {
    "path": "code/general/loop-vs-while_true.cr",
    "chars": 310,
    "preview": "require \"benchmark\"\n\nNUMBER = 100_000_000\n\ndef fast\n  index = 0\n  while true\n    break if index > NUMBER\n    index += 1\n"
  },
  {
    "path": "code/general/positional_argument-vs-named_argument.cr",
    "chars": 247,
    "preview": "require \"benchmark\"\n\nmodule M\n  def self.func(a, b, c)\n  end\nend\n\ndef fast\n  M.func(a: 1, b: 2, c: 3)\nend\n\ndef slow\n  M."
  },
  {
    "path": "code/general/property-vs-getter_and_setter.cr",
    "chars": 467,
    "preview": "require \"benchmark\"\n\nclass User\n  property :first_name\n\n  def initialize\n    @first_name = \"\"\n    @last_name = \"\"\n  end\n"
  },
  {
    "path": "code/hash/[]?-vs-has_key?.cr",
    "chars": 211,
    "preview": "require \"benchmark\"\n\nHASH = {\"a\" => \"z\"}\n\nBenchmark.ips do |x|\n  x.report(\"Hash#[]?\") do\n    HASH[\"a\"]?\n    HASH[\"b\"]?\n "
  },
  {
    "path": "code/hash/bracket-vs-fetch.cr",
    "chars": 217,
    "preview": "require \"benchmark\"\n\nHASH       = {\"fast\" => \"ruby\"}\nNAMEDTUPLE = {fast: \"ruby\"}\n\nBenchmark.ips do |x|\n  x.report(\"Hash#"
  },
  {
    "path": "code/hash/clone-vs-dup.cr",
    "chars": 210,
    "preview": "require \"benchmark\"\n\nHASH = (\"a\"..\"z\").map { |v| {v => v.bytes} }\n\ndef fast\n  HASH.dup\nend\n\ndef slow\n  HASH.clone\nend\n\nB"
  },
  {
    "path": "code/hash/keys-each-vs-each_key.cr",
    "chars": 1370,
    "preview": "require \"benchmark\"\n\nHASH = {\n  \"provider\" => \"facebook\",\n  \"uid\"      => \"1234567\",\n  \"info\"     => {\n    \"nickname\"   "
  },
  {
    "path": "code/hash/merge-bang-vs-[]=.cr",
    "chars": 318,
    "preview": "require \"benchmark\"\n\nENUM = (1..100)\n\ndef slow\n  ENUM.each_with_object({} of Int32 => Int32) do |e, h|\n    h.merge!({e ="
  },
  {
    "path": "code/namedtuple/bracket-vs-fetch.cr",
    "chars": 230,
    "preview": "require \"benchmark\"\n\nNAMEDTUPLE = {fast: \"ruby\"}\n\ndef fast\n  NAMEDTUPLE[:fast]\nend\n\ndef slow\n  NAMEDTUPLE.fetch(:fast, \""
  },
  {
    "path": "code/namedtuple/fetch-vs-fetch_with_block.cr",
    "chars": 329,
    "preview": "require \"benchmark\"\n\nHASH    = {writing: :fast_ruby}\nDEFAULT = \"fast ruby\"\n\nBenchmark.ips do |x|\n  x.report(\"NamedTuple#"
  },
  {
    "path": "code/proc-and-block/block-vs-to_proc.cr",
    "chars": 206,
    "preview": "require \"benchmark\"\n\nRANGE = (1..100)\n\ndef slow\n  RANGE.map { |i| i.to_s }\nend\n\ndef fast\n  RANGE.map(&.to_s)\nend\n\nBenchm"
  },
  {
    "path": "code/proc-and-block/proc-call-vs-yield.cr",
    "chars": 337,
    "preview": "require \"benchmark\"\n\ndef slow(&block)\n  block.call\nend\n\ndef slow2(&block)\n  yield\nend\n\ndef slow3(&block)\nend\n\ndef fast\n "
  },
  {
    "path": "code/string/concatenation.cr",
    "chars": 268,
    "preview": "require \"benchmark\"\n\nWORLD = \"world\"\n\ndef fastest\n  \"hello \" + WORLD\nend\n\ndef fast\n  \"hello #{WORLD}\"\nend\n\ndef slow\n  \"h"
  },
  {
    "path": "code/string/ends-string-matching-match-vs-end_with.cr",
    "chars": 210,
    "preview": "require \"benchmark\"\n\nSLUG = \"root_url\"\n\ndef fast\n  SLUG.ends_with?(\"_url\")\nend\n\ndef slow\n  SLUG =~ /_url$/\nend\n\nBenchmar"
  },
  {
    "path": "code/string/equal-substring-of-char.cr",
    "chars": 306,
    "preview": "require \"benchmark\"\n\ndef fastest\n  \"====\"[0] == '='\nend\n\ndef fast\n  \"====\"[0].to_s == \"=\"\nend\n\ndef slow\n  \"====\"[0] == \""
  },
  {
    "path": "code/string/equal-vs-match.cr",
    "chars": 253,
    "preview": "require \"benchmark\"\n\ndef fastest\n  \"foo\".match(/boo/)\nend\n\ndef fast\n  /boo/ === \"foo\"\nend\n\ndef slow\n  \"foo\" =~ /boo/\nend"
  },
  {
    "path": "code/string/gsub-vs-sub.cr",
    "chars": 483,
    "preview": "require \"benchmark\"\n\nURL = \"http://www.thelongestlistofthelongeststuffatthelongestdomainnameatlonglast.com/wearejustdoin"
  },
  {
    "path": "code/string/includes-vs-to_s.includes.cr",
    "chars": 220,
    "preview": "require \"benchmark\"\n\ndef slow\n  \"foobar\".includes?(\"crystal\")\nend\n\ndef fast\n  nil.to_s.includes?(\"crystal\")\nend\n\nBenchma"
  },
  {
    "path": "code/string/nil-vs-to_s.empty.cr",
    "chars": 176,
    "preview": "require \"benchmark\"\n\ndef slow\n  nil.to_s.empty?\nend\n\ndef fast\n  \"\".nil?\nend\n\nBenchmark.ips do |x|\n  x.report(\"String#nil"
  },
  {
    "path": "code/string/sub-vs-chomp.cr",
    "chars": 235,
    "preview": "require \"benchmark\"\n\nSLUG = \"YourSubclassType\"\n\ndef fast\n  SLUG.chomp(\"Type\")\nend\n\ndef slow\n  SLUG.sub(/Type\\z/, \"\")\nend"
  },
  {
    "path": "shard.yml",
    "chars": 166,
    "preview": "name: fast-crystal\nversion: 0.2.2\n\nauthors:\n  - icyleaf <icyleaf.cn@gmail.com>\n\ntargets:\n  fast-crystal:\n    main: src/f"
  },
  {
    "path": "src/fast-crystal.cr",
    "chars": 1747,
    "preview": "require \"file_utils\"\n\nBIN_PATH        = \"bin/code\"\nSOURCE_PATH     = File.expand_path(\"code\")\nCRYSTAL_BIN     = `which c"
  }
]

About this extraction

This page contains the full source code of the icyleaf/fast-crystal GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 38 files (27.6 KB), approximately 11.2k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!