mirror of https://github.com/tildeio/helix
Add fast_blank example
This commit is contained in:
parent
b33956b661
commit
ce6412819c
|
@ -1,8 +1,6 @@
|
|||
#[macro_use]
|
||||
extern crate helix;
|
||||
|
||||
use helix::{UncheckedValue, ToRust};
|
||||
|
||||
declare_types! {
|
||||
reopen class Array {
|
||||
def is_superset_of(self, needle: &[usize]) -> bool {
|
||||
|
@ -29,6 +27,10 @@ declare_types! {
|
|||
}
|
||||
}
|
||||
|
||||
// Delete me:
|
||||
|
||||
use helix::{UncheckedValue, ToRust};
|
||||
|
||||
impl AsRef<[usize]> for Array {
|
||||
fn as_ref(&self) -> &[usize] {
|
||||
let checked = self.0.to_checked().unwrap();
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
target
|
||||
*.bundle
|
||||
*.gem
|
|
@ -0,0 +1,24 @@
|
|||
[package]
|
||||
name = "turbo_blank"
|
||||
version = "0.1.0"
|
||||
authors = ["Godfrey Chan <godfreykfc@gmail.com>"]
|
||||
|
||||
[lib]
|
||||
|
||||
crate-type = ["staticlib"]
|
||||
|
||||
[dependencies]
|
||||
|
||||
libc = "*"
|
||||
|
||||
[dependencies.libcruby-sys]
|
||||
|
||||
path = "../../crates/libcruby-sys"
|
||||
|
||||
[dependencies.helix]
|
||||
|
||||
path = "../.."
|
||||
|
||||
[profile.release]
|
||||
|
||||
lto = true
|
|
@ -0,0 +1,5 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gemspec
|
||||
|
||||
gem 'helix_runtime', path: '../../ruby'
|
|
@ -0,0 +1,29 @@
|
|||
PATH
|
||||
remote: ../../ruby
|
||||
specs:
|
||||
helix_runtime (0.5.0)
|
||||
|
||||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
turbo_blank (0.1.0)
|
||||
helix_runtime
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
minitest (5.8.3)
|
||||
rake (10.5.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
bundler (~> 1.11)
|
||||
helix_runtime!
|
||||
minitest (~> 5.0)
|
||||
rake (~> 10.0)
|
||||
turbo_blank!
|
||||
|
||||
BUNDLED WITH
|
||||
1.11.2
|
|
@ -0,0 +1,34 @@
|
|||
require 'rake/clean'
|
||||
require 'rake/testtask'
|
||||
require 'bundler/setup'
|
||||
require 'bundler/gem_tasks'
|
||||
|
||||
directory 'target'
|
||||
directory 'lib/turbo_blank'
|
||||
|
||||
task :cargo_build do
|
||||
sh "cargo build --release"
|
||||
end
|
||||
CLEAN.include('target')
|
||||
|
||||
file "lib/turbo_blank/native.bundle" => ['lib/turbo_blank', :cargo_build] do
|
||||
sh "gcc -Wl,-force_load,target/release/libturbo_blank.a --shared -Wl,-undefined,dynamic_lookup -o lib/turbo_blank/native.bundle"
|
||||
end
|
||||
CLOBBER.include('lib/turbo_blank/native.bundle')
|
||||
|
||||
task :irb => "lib/turbo_blank/native.bundle" do
|
||||
exec "irb -Ilib -rturbo_blank"
|
||||
end
|
||||
|
||||
task :benchmark => "lib/turbo_blank/native.bundle" do
|
||||
exec "ruby -Ilib benchmark.rb"
|
||||
end
|
||||
|
||||
Rake::TestTask.new(:test) do |t|
|
||||
t.libs << "test"
|
||||
t.libs << "lib"
|
||||
t.test_files = FileList['test/**/*_test.rb']
|
||||
end
|
||||
|
||||
task :test => "lib/turbo_blank/native.bundle"
|
||||
task :default => :test
|
|
@ -0,0 +1,110 @@
|
|||
require 'bundler/setup'
|
||||
require 'benchmark'
|
||||
|
||||
ENV['IMPLEMENTATION'] = 'NONE'
|
||||
|
||||
require 'turbo_blank'
|
||||
|
||||
WARMUP_ITER = 10_000
|
||||
BENCHMARK_ITER = 2_000_000
|
||||
|
||||
puts "Benchmarking at #{BENCHMARK_ITER} iterations..."
|
||||
|
||||
def scenario(title, str, expected)
|
||||
title = " #{title} ".inspect
|
||||
|
||||
program = <<-RUBY_CODEZ
|
||||
str = #{str.inspect}
|
||||
|
||||
puts
|
||||
puts #{title}.center(80, '-')
|
||||
puts
|
||||
|
||||
# smoke test
|
||||
|
||||
unless str.rails_4_2_blank? == #{expected}
|
||||
raise "Expected " + str.inspect + ".rails_4_2_blank? to be #{expected}"
|
||||
end
|
||||
|
||||
unless str.rails_5_blank? == #{expected}
|
||||
raise "Expected " + str.inspect + ".rails_5_blank? to be #{expected}"
|
||||
end
|
||||
|
||||
unless str.is_blank == #{expected}
|
||||
raise "Expected " + str.inspect + ".is_blank to be #{expected}"
|
||||
end
|
||||
|
||||
# warmup
|
||||
i = 0
|
||||
|
||||
while i < #{WARMUP_ITER}
|
||||
str.rails_4_2_blank?
|
||||
str.rails_5_blank?
|
||||
str.is_blank
|
||||
i += 1
|
||||
end
|
||||
|
||||
# for realz
|
||||
GC.start
|
||||
|
||||
rails_4_2_result = Benchmark.measure {
|
||||
i = 0
|
||||
|
||||
while i < #{BENCHMARK_ITER}
|
||||
str.rails_4_2_blank?
|
||||
i += 1
|
||||
end
|
||||
}
|
||||
|
||||
GC.start
|
||||
|
||||
rails_5_result = Benchmark.measure {
|
||||
i = 0
|
||||
|
||||
while i < #{BENCHMARK_ITER}
|
||||
str.rails_5_blank?
|
||||
i += 1
|
||||
end
|
||||
}
|
||||
|
||||
GC.start
|
||||
|
||||
rust_result = Benchmark.measure {
|
||||
i = 0
|
||||
|
||||
while i < #{BENCHMARK_ITER}
|
||||
str.is_blank
|
||||
i += 1
|
||||
end
|
||||
}
|
||||
|
||||
# Should I use real time or...?
|
||||
puts "Rails 4.2 " + rails_4_2_result.real.round(5).to_s.ljust(7,"0") + " sec"
|
||||
puts "Rails 5 " + rails_5_result.real.round(5).to_s.ljust(7,"0") + " sec (" + (#{BENCHMARK_ITER}/rails_5_result.real).round.to_s.rjust(8) + " ops/sec) - " + (rails_4_2_result.real / rails_5_result.real).round(2).to_s.rjust(5) + "x faster"
|
||||
puts "Rust " + rust_result.real.round(5).to_s.ljust(7,"0") + " sec (" + (#{BENCHMARK_ITER}/rust_result.real).round.to_s.rjust(8) + " ops/sec) - " + (rails_4_2_result.real / rust_result.real).round(2).to_s.rjust(5) + "x faster"
|
||||
RUBY_CODEZ
|
||||
|
||||
eval program
|
||||
end
|
||||
|
||||
scenario("Empty string", "", true)
|
||||
scenario("Single space", " ", true)
|
||||
scenario("10 spaces", " ", true)
|
||||
scenario("Mixed", "\r\n\r\n ", true)
|
||||
|
||||
scenario("Not blank", "this is a test", false)
|
||||
scenario("Not blank (padded)", " this is a test", false)
|
||||
scenario("Not blank (long)",
|
||||
"this is a longer test
|
||||
this is a longer test
|
||||
this is a longer test
|
||||
this is a longer test
|
||||
this is a longer test",
|
||||
false)
|
||||
scenario("Not blank (long, padded)",
|
||||
" this is a longer test
|
||||
this is a longer test
|
||||
this is a longer test
|
||||
this is a longer test
|
||||
this is a longer test",
|
||||
false)
|
|
@ -0,0 +1,30 @@
|
|||
require "helix_runtime"
|
||||
|
||||
RubyString = String
|
||||
|
||||
require "turbo_blank/native"
|
||||
|
||||
class String
|
||||
BLANK_RE = /\A[[:space:]]*\z/
|
||||
|
||||
def rails_4_2_blank?
|
||||
BLANK_RE === self
|
||||
end
|
||||
|
||||
def rails_5_blank?
|
||||
empty? || BLANK_RE === self
|
||||
end
|
||||
|
||||
case ENV["IMPLEMENTATION"]
|
||||
when "RUST"
|
||||
alias blank? is_blank
|
||||
when "RAILS_4_2"
|
||||
alias blank? rails_4_2_blank?
|
||||
when "RAILS_5"
|
||||
alias blank? rails_5_blank?
|
||||
when "NONE"
|
||||
else
|
||||
puts "\nPlease specify an IMPLEMENTATION: RUST, RAILS_4_2, RAILS_5 or NONE"
|
||||
exit!
|
||||
end
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
module TurboBlank
|
||||
VERSION = "0.1.0"
|
||||
end
|
|
@ -0,0 +1,22 @@
|
|||
#[macro_use]
|
||||
extern crate helix;
|
||||
|
||||
declare_types! {
|
||||
reopen class RubyString {
|
||||
def is_blank(self) -> bool {
|
||||
// self.chars().all(|c| c.is_whitespace())
|
||||
self.to_string().chars().all(|c| c.is_whitespace())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete me:
|
||||
|
||||
use helix::{UncheckedValue, ToRust};
|
||||
|
||||
impl ToString for RubyString {
|
||||
fn to_string(&self) -> String {
|
||||
let checked = self.0.to_checked().unwrap();
|
||||
checked.to_rust()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
||||
require 'turbo_blank'
|
||||
|
||||
require 'minitest/autorun'
|
|
@ -0,0 +1,15 @@
|
|||
require 'test_helper'
|
||||
|
||||
class TurboBlankTest < Minitest::Test
|
||||
def test_blank
|
||||
assert_predicate '', :blank?
|
||||
assert_predicate ' ', :blank?
|
||||
assert_predicate " \n\t \r ", :blank?
|
||||
assert_predicate ' ', :blank?
|
||||
assert_predicate "\u00a0", :blank?
|
||||
end
|
||||
|
||||
def test_not_blank
|
||||
refute_predicate 'a', :blank?
|
||||
end
|
||||
end
|
|
@ -0,0 +1,34 @@
|
|||
# coding: utf-8
|
||||
lib = File.expand_path('../lib', __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
require 'turbo_blank/version'
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = "turbo_blank"
|
||||
spec.version = TurboBlank::VERSION
|
||||
spec.authors = ["Godfrey Chan"]
|
||||
spec.email = ["godfreykfc@gmail.com"]
|
||||
|
||||
spec.summary = %q{TODO: Write a short summary, because Rubygems requires one.}
|
||||
spec.description = %q{TODO: Write a longer description or delete this line.}
|
||||
spec.homepage = "TODO: Put your gem's website or public repo URL here."
|
||||
spec.license = "MIT"
|
||||
|
||||
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
||||
# delete this section to allow pushing this gem to any host.
|
||||
if spec.respond_to?(:metadata)
|
||||
spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
||||
else
|
||||
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
||||
end
|
||||
|
||||
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
||||
spec.bindir = "exe"
|
||||
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
||||
spec.require_paths = ["lib"]
|
||||
|
||||
spec.add_runtime_dependency "helix_runtime"
|
||||
spec.add_development_dependency "bundler", "~> 1.11"
|
||||
spec.add_development_dependency "rake", "~> 10.0"
|
||||
spec.add_development_dependency "minitest", "~> 5.0"
|
||||
end
|
Loading…
Reference in New Issue