functionable 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.adoc +63 -30
- data/functionable.gemspec +2 -2
- data.tar.gz.sig +0 -0
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c45d720e30ecc411d843fa883f806e9d7ce1214de6cd82293d6bfa2f1116b541
|
|
4
|
+
data.tar.gz: 2ea29d5add529473a0c51731bdf55f77d11a991dfc2f57970e2756cdb3467e75
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7dcd4d168cedae7291839e4c4017a249c1b48fed84d9d846c249b64d3416b731fa3811d00b2c7530cae6e6d90b87eaaaf703ffcf9903b34666ef0fedbe7fd758
|
|
7
|
+
data.tar.gz: 50fb7b77b3e3118f4982edbd326dc6b9b8353216d8f36e131d9fa6386515cd5d4c2d1c39fe5dc7a64bd0c08108755fd9136bcebf16b604cb2822ccfb68e42395
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/README.adoc
CHANGED
|
@@ -337,29 +337,41 @@ end
|
|
|
337
337
|
|
|
338
338
|
== Benchmarks
|
|
339
339
|
|
|
340
|
-
When you lean into the power of functional programming in Ruby, you gain performance and lower your memory footprint since you are creating the minimal amount of objects necessary. In terms of CPU performance, here's a
|
|
340
|
+
When you lean into the power of functional programming in Ruby, you gain performance and lower your memory footprint since you are creating the minimal amount of objects necessary. In terms of CPU performance, here's a benchmark script (see `bin/benchmark` included in this project):
|
|
341
341
|
|
|
342
342
|
[source,ruby]
|
|
343
343
|
----
|
|
344
|
+
#! /usr/bin/env ruby
|
|
345
|
+
# frozen_string_literal: true
|
|
346
|
+
|
|
344
347
|
require "bundler/inline"
|
|
345
348
|
|
|
346
349
|
gemfile true do
|
|
347
350
|
source "https://rubygems.org"
|
|
348
351
|
|
|
349
352
|
gem "benchmark-ips"
|
|
350
|
-
gem "functionable"
|
|
353
|
+
gem "functionable", path: ".."
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
module ModuleSelf
|
|
357
|
+
extend self
|
|
358
|
+
|
|
359
|
+
def call(message = "benchmark") = message
|
|
351
360
|
end
|
|
352
361
|
|
|
353
|
-
|
|
354
|
-
|
|
362
|
+
module ModuleFunction
|
|
363
|
+
module_function
|
|
355
364
|
|
|
356
|
-
|
|
365
|
+
def call(message = "benchmark") = message
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
module ModuleFunctionable
|
|
357
369
|
extend Functionable
|
|
358
370
|
|
|
359
371
|
def call(message = "benchmark") = message
|
|
360
372
|
end
|
|
361
373
|
|
|
362
|
-
class
|
|
374
|
+
class ClassFunction
|
|
363
375
|
def initialize message = "benchmark"
|
|
364
376
|
@message = message
|
|
365
377
|
end
|
|
@@ -371,16 +383,23 @@ class ClassExample
|
|
|
371
383
|
attr_reader :message
|
|
372
384
|
end
|
|
373
385
|
|
|
374
|
-
|
|
386
|
+
proc_function = proc { |message = "message"| message }
|
|
387
|
+
lambda_function = -> message = "benchmark" { message }
|
|
388
|
+
memoized_instance = ClassFunction.new
|
|
389
|
+
memoized_method = memoized_instance.method :call
|
|
375
390
|
|
|
376
391
|
Benchmark.ips do |benchmark|
|
|
377
392
|
benchmark.config time: 5, warmup: 2
|
|
378
393
|
|
|
379
|
-
benchmark.report("Proc") {
|
|
380
|
-
benchmark.report("Lambda") {
|
|
381
|
-
benchmark.report("Module") {
|
|
382
|
-
benchmark.report("
|
|
383
|
-
benchmark.report("
|
|
394
|
+
benchmark.report("Proc") { proc_function.call }
|
|
395
|
+
benchmark.report("Lambda") { lambda_function.call }
|
|
396
|
+
benchmark.report("Module (function)") { ModuleFunction.call }
|
|
397
|
+
benchmark.report("Module (functionable)") { ModuleFunctionable.call }
|
|
398
|
+
benchmark.report("Module (self)") { ModuleSelf.call }
|
|
399
|
+
benchmark.report("Class (new)") { ClassFunction.new.call }
|
|
400
|
+
benchmark.report("Class (memoized)") { memoized_instance.call }
|
|
401
|
+
benchmark.report("Method (new)") { memoized_instance.method(:call).call }
|
|
402
|
+
benchmark.report("Method (memoized)") { memoized_method.call }
|
|
384
403
|
|
|
385
404
|
benchmark.compare!
|
|
386
405
|
end
|
|
@@ -391,27 +410,41 @@ When you run the above benchmark, you should see the following results:
|
|
|
391
410
|
----
|
|
392
411
|
ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +YJIT +PRISM [arm64-darwin24.6.0]
|
|
393
412
|
Warming up --------------------------------------
|
|
394
|
-
Proc 2.
|
|
395
|
-
Lambda 2.
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
413
|
+
Proc 2.268M i/100ms
|
|
414
|
+
Lambda 2.327M i/100ms
|
|
415
|
+
Module (function) 3.984M i/100ms
|
|
416
|
+
Module (functionable)
|
|
417
|
+
4.143M i/100ms
|
|
418
|
+
Module (self) 4.177M i/100ms
|
|
419
|
+
Class (new) 1.266M i/100ms
|
|
420
|
+
Class (memoized) 4.128M i/100ms
|
|
421
|
+
Method (new) 775.573k i/100ms
|
|
422
|
+
Method (memoized) 2.053M i/100ms
|
|
399
423
|
Calculating -------------------------------------
|
|
400
|
-
Proc
|
|
401
|
-
Lambda 25.
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
424
|
+
Proc 24.944M (± 1.5%) i/s (40.09 ns/i) - 124.748M in 5.002287s
|
|
425
|
+
Lambda 25.683M (± 0.6%) i/s (38.94 ns/i) - 130.294M in 5.073248s
|
|
426
|
+
Module (function) 58.738M (± 2.9%) i/s (17.02 ns/i) - 294.792M in 5.022900s
|
|
427
|
+
Module (functionable)
|
|
428
|
+
58.607M (± 2.5%) i/s (17.06 ns/i) - 294.182M in 5.022770s
|
|
429
|
+
Module (self) 57.811M (± 2.4%) i/s (17.30 ns/i) - 292.388M in 5.060572s
|
|
430
|
+
Class (new) 14.801M (± 1.3%) i/s (67.56 ns/i) - 74.684M in 5.046650s
|
|
431
|
+
Class (memoized) 59.130M (± 0.4%) i/s (16.91 ns/i) - 297.230M in 5.026825s
|
|
432
|
+
Method (new) 9.030M (± 1.4%) i/s (110.74 ns/i) - 45.759M in 5.068493s
|
|
433
|
+
Method (memoized) 24.870M (± 0.2%) i/s (40.21 ns/i) - 125.231M in 5.035364s
|
|
405
434
|
|
|
406
435
|
Comparison:
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
436
|
+
Class (memoized): 59129953.7 i/s
|
|
437
|
+
Module (function): 58738432.2 i/s - same-ish: difference falls within error
|
|
438
|
+
Module (functionable): 58607417.9 i/s - same-ish: difference falls within error
|
|
439
|
+
Module (self): 57810666.8 i/s - same-ish: difference falls within error
|
|
440
|
+
Lambda: 25683494.8 i/s - 2.30x slower
|
|
441
|
+
Proc: 24943941.2 i/s - 2.37x slower
|
|
442
|
+
Method (memoized): 24870425.2 i/s - 2.38x slower
|
|
443
|
+
Class (new): 14801271.5 i/s - 3.99x slower
|
|
444
|
+
Method (new): 9029806.7 i/s - 6.55x slower
|
|
445
|
+
----
|
|
446
|
+
|
|
447
|
+
As you can see, a functional module is one of the fastest while everything else is much slower.
|
|
415
448
|
|
|
416
449
|
== Development
|
|
417
450
|
|
data/functionable.gemspec
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |spec|
|
|
4
4
|
spec.name = "functionable"
|
|
5
|
-
spec.version = "0.
|
|
5
|
+
spec.version = "0.1.0"
|
|
6
6
|
spec.authors = ["Brooke Kuhlmann"]
|
|
7
7
|
spec.email = ["brooke@alchemists.io"]
|
|
8
8
|
spec.homepage = "https://alchemists.io/projects/functionable"
|
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
|
22
22
|
spec.signing_key = Gem.default_key_path
|
|
23
23
|
spec.cert_chain = [Gem.default_cert_path]
|
|
24
24
|
|
|
25
|
-
spec.required_ruby_version = "
|
|
25
|
+
spec.required_ruby_version = ">= 3.4"
|
|
26
26
|
|
|
27
27
|
spec.extra_rdoc_files = Dir["README*", "LICENSE*"]
|
|
28
28
|
spec.files = Dir["*.gemspec", "lib/**/*"]
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: functionable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brooke Kuhlmann
|
|
@@ -63,7 +63,7 @@ require_paths:
|
|
|
63
63
|
- lib
|
|
64
64
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
|
-
- - "
|
|
66
|
+
- - ">="
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '3.4'
|
|
69
69
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
metadata.gz.sig
CHANGED
|
Binary file
|