fit_kit 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cfc4c2435b6e655fe41d4e467e373b5b282eaab6f738922d1d5a93721c8adaaa
4
- data.tar.gz: a1ab87078789a8e83fc13d9f2ee39bf4e060d35f2b290adbadd95e4def05afcf
3
+ metadata.gz: 6f5d819105551844f5a7e45a8399aa60b403cbc5b8b2adb278c0fb9a8a29631c
4
+ data.tar.gz: 1a55ae0af1a09860935dc3dee596a191c42133ae2a070c7c788514e4b4694248
5
5
  SHA512:
6
- metadata.gz: 2c25a7c3cb74581d959c406c89fa8a1df686c7632e52c52cab58c3b3a9bd1771e90ef7b0d2c67ae386e21a12d45eed52759dd951bc14b8b2a8622877d88d095c
7
- data.tar.gz: bc93a12200a50dd2d7cdaf4e9eaf165a7308ca59e83640ac26cd4b701305cda9a9b0e7908b885a7d55d4ec1281c5dc62db0b5ffbd57705ff1f8153c4ddb1ce4e
6
+ metadata.gz: 46cd84be49270a1197f815f776cc51627ba58d7abf72d8f0f4b6d80cb9f485ceca1a73745eb62df2696fe2a0cd3b78e2311550bf3f711dfcaf133daeed3abf1e
7
+ data.tar.gz: 32993953f6611a2ad85a70426be7525bb558e3cdf201e994e6848d04ab29f8ebdee3e1d722ac432173f05e799196f47a8f38e3d73c6f151c7de83497cdfa3463
data/README.md CHANGED
@@ -20,6 +20,50 @@ fit_data_records = ::FitKit.parse_fit_file(test_fit_file)
20
20
  # [RFitDataRecord, RFitDataRecord, RFitDataRecord ...]
21
21
  ```
22
22
 
23
+ ## Performance
24
+ Here is the performance parsing __4090__ fit files on my M1 Mac Mini (16G, 8 Cores) took 6 seconds (in parallel):
25
+
26
+ ```txt
27
+ ❯ ruby app.rb
28
+ Parsing 4090 fit files...
29
+ user system total real
30
+ 0.129862 0.102642 45.192900 ( 6.121117)
31
+ ```
32
+
33
+ Code to parse a given folder (contains __4090__ fit files) in parallel:
34
+
35
+ ```ruby
36
+ require 'fit_kit'
37
+ require 'benchmark'
38
+ require 'parallel'
39
+
40
+ def parse_concurrently
41
+ puts "Parsing all fit files here"
42
+ fit_files = Dir.glob("/Users/mikeli/docs/HealthFit/*.{fit,FIT}")
43
+ puts "Parsing #{fit_files.size} fit files..."
44
+
45
+ # Determine the number of processors
46
+ num_processors = Parallel.processor_count
47
+
48
+ # Parse files concurrently
49
+ Parallel.each(fit_files, in_processes: num_processors) do |file|
50
+ begin
51
+ FitKit.parse_fit_file(file)
52
+ rescue => e
53
+ puts "Error parsing #{file}: #{e.message}"
54
+ end
55
+ end
56
+ end
57
+
58
+
59
+ Benchmark.bm do |x|
60
+ x.report do
61
+ parse_concurrently
62
+ end
63
+ end
64
+
65
+ ```
66
+
23
67
  ## Contributing
24
68
 
25
69
  Bug reports and pull requests are welcome on GitHub at https://github.com/29decibel/fit_kit. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/29decibel/fit_kit/blob/main/CODE_OF_CONDUCT.md).
@@ -1,12 +1,7 @@
1
- use fitparser::{self, FitDataField, FitDataRecord, Value};
2
- use magnus::{function, method, prelude::*, Error, IntoValue, RArray, Ruby};
1
+ use fitparser::{self, FitDataRecord, Value};
2
+ use magnus::{function, method, prelude::*, Error, IntoValue, RArray, RHash, Ruby, Symbol};
3
3
  use std::fs::File;
4
4
 
5
- ///////////////////////// RFitDataField ///////////////////////////
6
- // define a wrapper ruby class for FitDataField
7
- #[magnus::wrap(class = "RFitDataField")]
8
- struct RFitDataField(FitDataField);
9
-
10
5
  // recursive method to turn Fit value into magnus::Value
11
6
  fn value_to_rb_value(value: &Value) -> magnus::Value {
12
7
  match value {
@@ -38,16 +33,6 @@ fn value_to_rb_value(value: &Value) -> magnus::Value {
38
33
  }
39
34
  }
40
35
 
41
- impl RFitDataField {
42
- fn name(&self) -> String {
43
- self.0.name().to_string()
44
- }
45
-
46
- fn value(&self) -> magnus::Value {
47
- value_to_rb_value(self.0.value())
48
- }
49
- }
50
-
51
36
  ///////////////////////// RFitDataRecord ///////////////////////////
52
37
  #[magnus::wrap(class = "RFitDataRecord")]
53
38
  struct RFitDataRecord(FitDataRecord);
@@ -57,28 +42,29 @@ impl RFitDataRecord {
57
42
  self.0.kind().to_string()
58
43
  }
59
44
 
60
- fn fields(&self) -> RArray {
61
- let array = RArray::new();
45
+ fn fields_hash(&self) -> RHash {
46
+ let hash = RHash::new();
62
47
  for field in self.0.fields() {
63
- array.push(RFitDataField(field.clone())).unwrap();
48
+ let value = value_to_rb_value(field.value());
49
+ let pair = RHash::new();
50
+ pair.aset(Symbol::new("units"), field.units()).unwrap();
51
+ pair.aset(Symbol::new("value"), value).unwrap();
52
+ // here we add the stuff to the hash
53
+ let field_name_symbol = Symbol::new(field.name());
54
+ hash.aset(field_name_symbol, pair).unwrap();
64
55
  }
65
- array
56
+
57
+ hash
66
58
  }
67
59
  }
68
60
 
69
61
  // Here we define two ruby classes
70
62
  // RFitDataRecord and RFitDataField
71
63
  fn define_ruby_classes(ruby: &Ruby) -> Result<(), magnus::Error> {
72
- let class = ruby.define_class("RFitDataField", ruby.class_object())?;
73
-
74
- // define bunch of methods
75
- class.define_method("name", method!(RFitDataField::name, 0))?;
76
- class.define_method("value", method!(RFitDataField::value, 0))?;
77
-
78
64
  // definie the the other one here
79
65
  let data_record_class = ruby.define_class("RFitDataRecord", ruby.class_object())?;
80
66
  data_record_class.define_method("kind", method!(RFitDataRecord::kind, 0))?;
81
- data_record_class.define_method("fields", method!(RFitDataRecord::fields, 0))?;
67
+ data_record_class.define_method("fields_hash", method!(RFitDataRecord::fields_hash, 0))?;
82
68
 
83
69
  Ok(())
84
70
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FitKit
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fit_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - 29decibel
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-10-15 00:00:00.000000000 Z
11
+ date: 2024-10-16 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Garmin fit file parser wrapping Rust crate fitparse_rs.
14
14
  email: