faster_path 0.2.6 → 0.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64eada185c9f0597ca475f6f94f77299b5ebf0458fe6de87d5a041d7a6d69dfe
4
- data.tar.gz: 5d14a11a8a468eba873da3b6e4d2628e8fdbb5d88150c60575b6266a4df5f726
3
+ metadata.gz: 84e796cda8b8704b7a6f5e2a2e69acc012f611b66f89642f34149f88c645ae34
4
+ data.tar.gz: 8b20ae9b2bcaebaf44dbc56500ad539e5082169d729a24685c0c9a446ee4dd6b
5
5
  SHA512:
6
- metadata.gz: 2c2121f4aa08b8979818480b78980f07563483befa52c2493821f7a562d0f213a762f192ed1b7ec3c67050c9f0a72bccbb65a0dcb1d7258316ffbe0ae7480c2f
7
- data.tar.gz: 0c16b9cd5e5ff583717d664228bfac6ac4b6b5e46c7a92c8a3170ae050ae9ec6974dc597a1c9aff8232e77515b3d5cd70bfccd33c5fa67402091af660dd7f502
6
+ metadata.gz: '091d419f3c849b46f493a3ae47fcf59d064c83ffec898856032ffa47d84e68ace558e882437f95a662bd84b77cdbe0182f7b62c5cd1316fd250a54d49afe3046'
7
+ data.tar.gz: ecbdcad442c08c9eee827f30672f585f34450e0b4a72905936fe49a7eb251a7e8c461a0a5fcaa10d19a1e36ef304ada0b8b8f1bff1d0cab31017bad35ddd3743
data/Cargo.toml CHANGED
@@ -8,6 +8,9 @@ repository = "https://github.com/danielpclark/faster_path"
8
8
  license = "MIT OR Apache-2.0"
9
9
  readme = "README.md"
10
10
 
11
+ [package.metadata.thermite]
12
+ github_releases = true
13
+
11
14
  [lib]
12
15
  name = "faster_path"
13
16
  crate-type = ["dylib"]
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![TravisCI Build Status](https://travis-ci.org/danielpclark/faster_path.svg?branch=master)](https://travis-ci.org/danielpclark/faster_path)
4
4
  [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/10ul0gk3cwhlt2lj/branch/master?svg=true)](https://ci.appveyor.com/project/danielpclark/faster-path/branch/master)
5
5
  [![Latest Tag](https://img.shields.io/github/tag/danielpclark/faster_path.svg)](https://github.com/danielpclark/faster_path/tags)
6
- [![Commits Since Last Release](https://img.shields.io/github/commits-since/danielpclark/faster_path/v0.2.6.svg)](https://github.com/danielpclark/faster_path/pulse)
6
+ [![Commits Since Last Release](https://img.shields.io/github/commits-since/danielpclark/faster_path/v0.3.1.svg)](https://github.com/danielpclark/faster_path/pulse)
7
7
  [![Binary Release](https://img.shields.io/github/release/danielpclark/faster_path.svg)](https://github.com/danielpclark/faster_path/releases)
8
8
  [![Coverage Status](https://coveralls.io/repos/github/danielpclark/faster_path/badge.svg)](https://coveralls.io/github/danielpclark/faster_path)
9
9
  [![Inline docs](http://inch-ci.org/github/danielpclark/faster_path.svg?branch=master)](http://inch-ci.org/github/danielpclark/faster_path)
@@ -55,7 +55,7 @@ Running `stackprof tmp/2016-06-09T00:42:10-04:00-stackprof-cpu-myapp.dump`. Exec
55
55
  108 (1.5%) 14 (0.2%) ActionView::Helpers::AssetUrlHelper#asset_path
56
56
  ```
57
57
 
58
- Here are some addtional stats. From Rails loading to my home page, these methods are called _(not directly, Rails & gems call them)_ this many times. And the home page has minimal content.
58
+ Here are some additional stats. From Rails loading to my home page, these methods are called _(not directly, Rails & gems call them)_ this many times. And the home page has minimal content.
59
59
  ```ruby
60
60
  Pathname#to_s called 29172 times.
61
61
  Pathname#<=> called 24963 times.
@@ -97,8 +97,10 @@ I've said this about Sprockets but this required two other gems to be updated as
97
97
  ## Status
98
98
 
99
99
  * Rust compilation is working
100
- * Methods are _most likely_ stable
101
- * Testers and developers are most welcome!
100
+ * Methods are stable
101
+ * Thoroughly tested
102
+ * Testers and developers are most welcome
103
+ * Windows & encoding support is underway!
102
104
 
103
105
  ## Installation
104
106
 
@@ -113,7 +115,7 @@ curl -sSf https://static.rust-lang.org/rustup.sh | sh
113
115
  Add this line to your application's Gemfile:
114
116
 
115
117
  ```ruby
116
- gem 'faster_path', '~> 0.2.3'
118
+ gem 'faster_path', '~> 0.3.1'
117
119
  ```
118
120
 
119
121
  And then execute:
@@ -147,6 +149,7 @@ Current methods implemented:
147
149
  | `FasterPath.del_trailing_separator` | `Pathname#del_trailing_separator` | 80.6% |
148
150
  | `FasterPath.directory?` | `Pathname#directory?` | 11.3% |
149
151
  | `FasterPath.entries` | `Pathname#entries` | 8.4% |
152
+ | `FasterPath.extname` | `File.extname` | 41.2% |
150
153
  | `FasterPath.has_trailing_separator?` | `Pathname#has_trailing_separator` | 67.6% |
151
154
  | `FasterPath.plus` | `Pathname#join` | 66.4% |
152
155
  | `FasterPath.plus` | `Pathname#plus` | 81.4% |
@@ -181,10 +184,9 @@ These will **not** be included by default in monkey-patches. Be cautious when u
181
184
  |---|---|
182
185
  | `FasterPath.dirname` | `File.dirname` |
183
186
  | `FasterPath.basename` | `File.basename` |
184
- | `FasterPath.extname` | `File.extname` |
185
187
 
186
188
  It's been my observation (and some others) that the Rust implementation of the C code for `File` has similar results but
187
- performance seems to vary based on CPU cache on possibly 64bit/32bit system environmnets. When these methods were initially written, and somewhat simplistic, they were faster than the C implementations on `File`. After the implementations have been perfected to match the behavior in Ruby they don't perform as well and are therefore not included by default when the monkey patch method `FasterPath.sledgehammer_everything!` is executed. If you don't want to pass the `WITH_REGRESSION` environment variable you can put any turthy parameter on the monkey patch method to include it.
189
+ performance seems to vary based on CPU cache on possibly 64bit/32bit system environments. When these methods were initially written, and somewhat simplistic, they were faster than the C implementations on `File`. After the implementations have been perfected to match the behavior in Ruby they don't perform as well and are therefore not included by default when the monkey patch method `FasterPath.sledgehammer_everything!` is executed.
188
190
 
189
191
  ## Getting Started with Development
190
192
 
@@ -205,13 +207,7 @@ Learn and share performance tips on the [wiki](https://github.com/danielpclark/f
205
207
 
206
208
  ### Building and running tests
207
209
 
208
- First, bundle the gem's development dependencies by running `bundle`.
209
-
210
- Then, build the rust code:
211
-
212
- ```sh
213
- rake build_src
214
- ```
210
+ First, bundle the gem's development dependencies by running `bundle`. Rust compilation is included in the current rake commands.
215
211
 
216
212
  FasterPath is tested with [The Ruby Spec Suite](https://github.com/ruby/spec) to ensure it is compatible with the
217
213
  native implementation, and also has its own test suite testing its monkey-patching and refinements functionality.
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
3
- require 'fileutils'
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+ require 'thermite/tasks'
4
4
 
5
5
  desc 'System Details'
6
6
  task :sysinfo do
@@ -24,6 +24,8 @@ task :sysinfo do
24
24
  end
25
25
  end
26
26
 
27
+ thermite = Thermite::Tasks.new
28
+
27
29
  desc "Generate Contriburs.md Manifest"
28
30
  task :contrib do
29
31
  puts "Generating Contriburs.md Manifest"
@@ -61,36 +63,16 @@ task :libruby_debug do
61
63
  puts "libruby.so copied."
62
64
  end
63
65
 
64
- desc "Build Rust extension"
65
- task build_src: :libruby_release do
66
- puts "Building extension..."
67
- sh "cargo build --release"
68
- end
69
-
70
- desc "Clean up Rust build"
71
- task :clean_src do
72
- puts "Cleaning up build..."
73
- # Remove all but library file
74
- FileUtils.
75
- rm_rf(
76
- Dir.
77
- glob('target/release/*').
78
- keep_if do |f|
79
- !f[/\.(?:so|dll|dylib|deps)\z/]
80
- end
81
- )
66
+ desc 'Build + clean up Rust extension'
67
+ task build_lib: 'thermite:build' do
68
+ thermite.run_cargo 'clean'
82
69
  end
83
70
 
84
- desc "Build + clean up Rust extension"
85
- task build_lib: [:build_src, :clean_src] do
86
- puts "Completed build!"
87
- end
88
-
89
- desc "Code Quality Check"
71
+ desc 'Code Quality Check'
90
72
  task :lint do
91
73
  puts
92
- puts "Quality check starting..."
93
- sh "rubocop"
74
+ puts 'Quality check starting...'
75
+ sh 'rubocop'
94
76
  puts
95
77
  end
96
78
 
@@ -100,9 +82,8 @@ task cargo: :libruby_debug do
100
82
  end
101
83
 
102
84
  Rake::TestTask.new(minitest: :build_lib) do |t|
103
- t.libs << "test"
104
- t.libs << "lib"
105
- t.test_files = FileList['test/**/*_test.rb']
85
+ t.libs = %w[lib test]
86
+ t.pattern = 'test/**/*_test.rb'
106
87
  end
107
88
 
108
89
  task :init_mspec do |_t|
data/ext/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'thermite/tasks'
2
+
3
+ project_toplevel_dir = File.dirname(File.dirname(__FILE__))
4
+ Thermite::Tasks.new(cargo_project_path: project_toplevel_dir,
5
+ ruby_project_path: project_toplevel_dir)
6
+
7
+ task default: 'thermite:build'
data/faster_path.gemspec CHANGED
@@ -16,21 +16,22 @@ Gem::Specification.new do |spec|
16
16
  spec.files = [
17
17
  "Cargo.lock", "Cargo.toml", "Gemfile",
18
18
  "MIT-LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup",
19
- "ext/faster_path/extconf.rb", "faster_path.gemspec"
19
+ "ext/Rakefile", "faster_path.gemspec"
20
20
  ]
21
21
  spec.files += Dir['lib/**/*']
22
22
  spec.files += Dir['src/**/*']
23
23
 
24
- spec.extensions << "ext/faster_path/extconf.rb"
24
+ spec.extensions = ["ext/Rakefile"]
25
25
  spec.require_paths = ["lib"]
26
26
 
27
27
  spec.add_dependency "bundler", "~> 1.12"
28
28
  spec.add_dependency "rake", "~> 12.0"
29
+ spec.add_dependency "thermite", "~> 0.13.0"
29
30
  spec.add_development_dependency "read_source", "~> 0.2.6"
30
31
  spec.add_development_dependency "minitest", "~> 5.10"
31
32
  spec.add_development_dependency "minitest-reporters", "~> 1.1"
32
33
  spec.add_development_dependency "color_pound_spec_reporter", "~> 0.0.9"
33
- spec.add_development_dependency "rubocop", "~> 0.51"
34
+ spec.add_development_dependency "rubocop", "0.53"
34
35
  spec.add_development_dependency "stop_watch", "~> 1.0"
35
36
  if !ENV['CI'] && ENV['GRAPH']
36
37
  spec.add_development_dependency "gruff", "~> 0.7.0"
data/lib/faster_path.rb CHANGED
@@ -1,11 +1,16 @@
1
- require "faster_path/version"
1
+ require 'faster_path/version'
2
2
  require 'pathname'
3
- require 'faster_path/platform'
3
+ require 'thermite/config'
4
4
  require 'fiddle'
5
5
  require 'fiddle/import'
6
6
 
7
7
  module FasterPath
8
- FFI_LIBRARY = FasterPath::Platform.ffi_library()
8
+ FFI_LIBRARY = begin
9
+ toplevel_dir = File.dirname(__dir__)
10
+ config = Thermite::Config.new(cargo_project_path: toplevel_dir,
11
+ ruby_project_path: toplevel_dir)
12
+ config.ruby_extension_path
13
+ end
9
14
 
10
15
  Fiddle::Function.
11
16
  new(Fiddle.dlopen(FFI_LIBRARY)['Init_faster_pathname'], [], Fiddle::TYPE_VOIDP).
Binary file
@@ -10,7 +10,7 @@ module FasterPath
10
10
  pth = pth.to_path if pth.respond_to? :to_path
11
11
  raise TypeError unless pth.is_a?(String) && ext.is_a?(String)
12
12
  FasterPath.basename(pth, ext)
13
- end
13
+ end if !!ENV['WITH_REGRESSION']
14
14
 
15
15
  def self.extname(pth)
16
16
  pth = pth.to_path if pth.respond_to? :to_path
@@ -22,7 +22,7 @@ module FasterPath
22
22
  pth = pth.to_path if pth.respond_to? :to_path
23
23
  raise TypeError unless pth.is_a? String
24
24
  FasterPath.dirname(pth)
25
- end
25
+ end if !!ENV['WITH_REGRESSION']
26
26
  end
27
27
  end
28
28
 
@@ -96,8 +96,8 @@ module FasterPath
96
96
  end
97
97
  private_constant :MonkeyPatches
98
98
 
99
- def self.sledgehammer_everything!(include_file = !!ENV['WITH_REGRESSION'])
100
- MonkeyPatches._ruby_core_file! if include_file # SLOW; DON'T AUTO INCLUDE
99
+ def self.sledgehammer_everything!()
100
+ MonkeyPatches._ruby_core_file!
101
101
  MonkeyPatches._ruby_library_pathname!
102
102
  "CAUTION: Monkey patching effects everything! Be very sure you want this!"
103
103
  end
@@ -1,3 +1,3 @@
1
1
  module FasterPath
2
- VERSION = "0.2.6"
2
+ VERSION = "0.3.1"
3
3
  end
data/src/extname.rs CHANGED
@@ -1,13 +1,63 @@
1
- use path_parsing::extract_last_path_segment;
1
+ use path_parsing::SEP;
2
+ use std::str;
3
+
4
+ struct ExtnameCoords {
5
+ word: bool,
6
+ pred: bool,
7
+ dot: bool,
8
+ start: usize,
9
+ end: usize,
10
+ }
11
+
12
+ impl ExtnameCoords {
13
+ pub fn dec(&mut self) {
14
+ self.start -= 1;
15
+ if !self.word {
16
+ self.end -= 1;
17
+ }
18
+ }
19
+ }
2
20
 
3
21
  pub fn extname(pth: &str) -> &str {
4
- let name = extract_last_path_segment(pth);
22
+ let path = pth.as_bytes();
23
+ let mut extname = ExtnameCoords {
24
+ word: false,
25
+ pred: false,
26
+ dot: false,
27
+ start: path.len(),
28
+ end: path.len(),
29
+ };
5
30
 
6
- if let Some(dot_i) = name.rfind('.') {
7
- if dot_i > 0 && dot_i < name.len() - 1 && name[..dot_i].chars().rev().next().unwrap() != '.' {
8
- return &name[dot_i..]
31
+ for &item in path.iter().rev() {
32
+ if (item == b'.' && !extname.dot) || item == SEP {
33
+ if item == SEP && extname.word {
34
+ return ""
35
+ }
36
+
37
+ if !extname.pred {
38
+ extname.dec();
39
+ }
40
+
41
+ if extname.word {
42
+ extname.dot = true;
43
+ }
44
+ } else {
45
+ if extname.dot {
46
+ extname.pred = true;
47
+ break;
48
+ } else {
49
+ extname.word = true;
50
+ }
51
+
52
+ if !extname.pred {
53
+ extname.dec()
54
+ }
9
55
  }
10
56
  }
11
57
 
12
- ""
58
+ if !extname.pred {
59
+ return "";
60
+ }
61
+
62
+ str::from_utf8(&path[extname.start..extname.end]).unwrap_or("")
13
63
  }
data/src/path_parsing.rs CHANGED
@@ -1,5 +1,4 @@
1
1
  extern crate memchr;
2
- use self::memchr::memrchr;
3
2
  use std::path::MAIN_SEPARATOR;
4
3
  use std::str;
5
4
 
@@ -8,11 +7,6 @@ lazy_static! {
8
7
  pub static ref SEP_STR: &'static str = str::from_utf8(&[SEP]).unwrap();
9
8
  }
10
9
 
11
- pub fn extract_last_path_segment(path: &str) -> &str {
12
- let end = (last_non_sep_i(path) + 1) as usize;
13
- &path[memrchr(SEP, &path.as_bytes()[..end]).unwrap_or(0)..end]
14
- }
15
-
16
10
  // Returns the byte offset of the last byte preceding a MAIN_SEPARATOR.
17
11
  pub fn last_non_sep_i(path: &str) -> isize {
18
12
  last_non_sep_i_before(path, path.len() as isize - 1)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faster_path
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel P. Clark
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-03 00:00:00.000000000 Z
11
+ date: 2018-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '12.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: thermite
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.13.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.13.0
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: read_source
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -98,16 +112,16 @@ dependencies:
98
112
  name: rubocop
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
- - - "~>"
115
+ - - '='
102
116
  - !ruby/object:Gem::Version
103
- version: '0.51'
117
+ version: '0.53'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
- - - "~>"
122
+ - - '='
109
123
  - !ruby/object:Gem::Version
110
- version: '0.51'
124
+ version: '0.53'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: stop_watch
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -127,7 +141,7 @@ email:
127
141
  - 6ftdan@gmail.com
128
142
  executables: []
129
143
  extensions:
130
- - ext/faster_path/extconf.rb
144
+ - ext/Rakefile
131
145
  extra_rdoc_files: []
132
146
  files:
133
147
  - Cargo.lock
@@ -138,12 +152,12 @@ files:
138
152
  - Rakefile
139
153
  - bin/console
140
154
  - bin/setup
141
- - ext/faster_path/extconf.rb
155
+ - ext/Rakefile
142
156
  - faster_path.gemspec
143
157
  - lib/faster_path.rb
158
+ - lib/faster_path.so
144
159
  - lib/faster_path/optional/monkeypatches.rb
145
160
  - lib/faster_path/optional/refinements.rb
146
- - lib/faster_path/platform.rb
147
161
  - lib/faster_path/version.rb
148
162
  - src/basename.rs
149
163
  - src/chop_basename.rs
@@ -1,19 +0,0 @@
1
- require 'mkmf'
2
-
3
- have_header('Dummy Makefile')
4
-
5
- unless find_executable('cargo')
6
- puts "You need to have Rust installed for this gem to build natively."
7
- puts "Please install the latest nightly build:"
8
- puts
9
- puts "curl -sSf https://static.rust-lang.org/rustup.sh | sudo sh -s -- --channel=nightly"
10
- puts
11
- at_exit { puts "Exiting..."}
12
- end
13
-
14
- Dir.chdir(File.expand_path("../../", File.dirname(__FILE__))) do
15
- `rake build_src`
16
- `rake clean_src`
17
- end
18
-
19
- create_makefile('faster_path/dummy')
@@ -1,60 +0,0 @@
1
- module FasterPath
2
- module Platform
3
- class << self
4
- def ffi_library
5
- file = [
6
- lib_prefix,
7
- "faster_path.",
8
- lib_suffix
9
- ]
10
-
11
- File.join(rust_release, file.join())
12
- end
13
-
14
- def operating_system
15
- case host_os()
16
- when /linux|bsd|solaris/
17
- "linux"
18
- when /darwin/
19
- "darwin"
20
- when /mingw|mswin/
21
- "windows"
22
- else
23
- host_os()
24
- end
25
- end
26
-
27
- def lib_prefix
28
- case operating_system()
29
- when /windows/
30
- ''
31
- when /cygwin/
32
- 'cyg'
33
- else
34
- 'lib'
35
- end
36
- end
37
-
38
- def lib_suffix
39
- case operating_system()
40
- when /darwin/
41
- 'dylib'
42
- when /linux/
43
- 'so'
44
- when /windows|cygwin/
45
- 'dll'
46
- else
47
- 'so'
48
- end
49
- end
50
-
51
- def rust_release
52
- File.expand_path("../../target/release/", __dir__)
53
- end
54
-
55
- def host_os
56
- RbConfig::CONFIG['host_os'].downcase
57
- end
58
- end
59
- end
60
- end