"Introduction à la programmation pratique de Rust" Reportez-vous aux pages 421-427 et appelez les fonctions Rust de Ruby. À propos, aujourd'hui (vendredi 4 septembre 2020) c'est Ruby Kaigi.
Téléchargez Ruby pour Windows depuis RubyInstaller pour Windows. Au moment de la rédaction de cet article, le dernier est [Ruby + Devkit 2.7.1-1 (x64)](https://github.com/oneclick/rubyinstaller2/releases/download/RubyInstaller-2.7.1-1/rubyinstaller-devkit-2.7. 1-1-x64.exe).
Il y a "En cas de doute, appuyez sur ENTER", appuyez donc sur ENTER pour continuer.
Puisqu'il dit "Installation réussie de la chaîne d'outils de développement MSYS2 et MINGW", ENTER était-il identique à appuyer sur 3? Appuyez maintenant sur ENTRÉE pour terminer l'installation.
Vérifiez le fonctionnement de ruby sur Windows PowerShell.
PS > ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x64-mingw32]
Vous pouvez le vérifier avec VS Code en rouvrant TERMINAL.
Créez un répertoire de projet pour mener les expériences en p.421.
PS > cargo new ffitest
Created binary (application) `ffitest` package
Créez un exemple de répertoire sous ffitest, écrivez du code Ruby et testez le traitement Ruby.
ffitest/sample/add_array.rb
def add_array(n,x)
a = Array.new(n,0)
x.times do
for i in 0..x-1
a[i] += 1
end
end
a.sum
end
puts add_array(ARGV[0].to_i, ARGV[1].to_i)
Measure-Command équivaut à «time» sous Linux commander.
PS ffitest\sample> Measure-Command {ruby add_array.rb 10000 10000}
Days : 0
Hours : 0
Minutes : 0
Seconds : 8
Milliseconds : 53
Ticks : 80530169
TotalDays : 9.32062141203704E-05
TotalHours : 0.00223694913888889
TotalMinutes : 0.134216948333333
TotalSeconds : 8.0530169
TotalMilliseconds : 8053.0169
À partir de TotalSeconds, vous pouvez voir que cela prend environ 8 secondes.
Vient ensuite le côté Rust. Renommez src / main.rs en src / add_array.rs.
src/add_array.rs
fn add_array(n: u64, x: u64) -> u64 {
let mut a = vec![0u64; n as usize];
for _ in 0..x {
for i in 0..n as usize {
a[i] += 1;
}
}
a.iter().sum()
}
use std::env;
fn main() {
let args: Vec<_> = env::args().collect();
let n = args[1].parse::<u64>().unwrap();
let x = args[2].parse::<u64>().unwrap();
println!("{}", add_array(n, x));
}
Ajoutez le paramètre d'exécution de add_array à Cargo.toml.
Cargo.toml
[[bin]]
name = "add_array"
path = "src/add_array.rs"
p.422 Vérifiez la construction et l'exécution en bas.
PS ffitest> cargo build --release
Compiling ffitest v0.1.0 (ffitest)
Finished release [optimized] target(s) in 1.29s
PS ffitest> Measure-Command {./target/release/add_array 10000 10000}
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 93
Ticks : 935455
TotalDays : 1.0827025462963E-06
TotalHours : 2.59848611111111E-05
TotalMinutes : 0.00155909166666667
TotalSeconds : 0.0935455
TotalMilliseconds : 93.5455
0,09 seconde. C'est vraiment rapide.
Créez un répertoire de projet pour la bibliothèque.
PS > cargo new --lib addarray
Created library `addarray` package
[Spécification de la bibliothèque dynamique] dans Cargo.toml (https://doc.rust-lang.org/edition-guide/rust-2018/platform-and-target-support/cdylib-crates-for-c-interoperability.html )Je fais.
addarray/Cargo.toml
[lib]
crate-type = ["cdylib"]
Par le travail jusqu'à présent, src / lib.rs a été créé. Le contenu est le suivant.
src/lib.rs
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
Effacez le code ci-dessus et écrivez-le selon la deuxième lib.rs de la p.424.
src/lib.rs
#[no_mangle]
pub extern "C" fn add_array(n: u64, x: u64) -> u64 {
let mut a = vec![0u64; n as usize];
for _ in 0..x {
for i in 0..n as usize {
a[i] += 1;
}
}
a.iter().sum()
}
Construire. En raison de diverses pensées et erreurs, si --target = x86_64-pc-windows-msvc
est défini, il semble que ce sera une DLL qui peut être exécutée avec ce Ruby (recherche insuffisante).
PS > cargo build --release --target=x86_64-pc-windows-msvc
Compiling addarray v0.1.0 (addarray)
Finished release [optimized] target(s) in 0.87s
Vérifiez la bibliothèque créée.
PS addarray> ls .\target\x86_64-pc-windows-msvc\release\
annuaire: addarray\target\x86_64-pc-windows-msvc\release
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2020/09/04 --:-- .fingerprint
d----- 2020/09/04 --:-- build
d----- 2020/09/04 --:-- deps
d----- 2020/09/04 --:-- examples
d----- 2020/09/04 --:-- incremental
-a---- 2020/09/04 --:-- 0 .cargo-lock
-a---- 2020/09/04 --:-- 109 addarray.d
-a---- 2020/09/04 --:-- 128512 addarray.dll
-a---- 2020/09/04 --:-- 980 addarray.dll.exp
-a---- 2020/09/04 --:-- 1942 addarray.dll.lib
-a---- 2020/09/04 --:-- 937984 addarray.pdb
OK si addarray.dll est créé.
Installez Ruby ffi.
PS > gem install ffi
Fetching ffi-1.13.1-x64-mingw32.gem
Successfully installed ffi-1.13.1-x64-mingw32
Parsing documentation for ffi-1.13.1-x64-mingw32
Installing ri documentation for ffi-1.13.1-x64-mingw32
Done installing documentation for ffi after 1 seconds
1 gem installed
Le code source Ruby est créé en tant que addarray / sample / add_array_rs.rb. Soyez prudent lorsque vous spécifiez le chemin de la DLL. J'étais accro à la spécification d'un chemin relatif, alors j'ai spécifié un chemin absolu.
addarray/sample/add_array_rs.rb
require 'ffi'
module AddArray
extend FFI::Library
ffi_lib 'C:\your\path\addarray\target\x86_64-pc-windows-msvc\release\addarray.dll'
attach_function :add_array, [:uint64, :uint64], :uint64
end
puts AddArray::add_array(ARGV[0].to_i, ARGV[1].to_i)
PS addarray\sample> Measure-Command {ruby .\add_array_rs.rb 10000 10000}
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 311
Ticks : 3111198
TotalDays : 3.60092361111111E-06
TotalHours : 8.64221666666667E-05
TotalMinutes : 0.00518533
TotalSeconds : 0.3111198
TotalMilliseconds : 311.1198
0,3 seconde. C'est plus lent que 0,09 seconde, mais c'était à l'origine 8 secondes, donc c'est une grande amélioration.
Lorsqu'il est exécuté sous Windows, Rust doit créer une DLL appropriée en fonction de l'environnement Ruby. J'étais accro à l'écueil et j'ai enquêté sur des notes diverses.
Lors de l'ajout d'une cible de MINGW64.
PS > rustup target add x86_64-pc-windows-gnu
info: downloading component 'rust-std' for 'x86_64-pc-windows-gnu'
info: installing component 'rust-std' for 'x86_64-pc-windows-gnu'
info: Defaulting to 500.0 MiB unpack ram
14.1 MiB / 14.1 MiB (100 %) 10.9 MiB/s in 1s ETA: 0s
Utilisez rustup pour voir la liste des cibles.
PS addarray> rustup show
Default host: x86_64-pc-windows-msvc
rustup home: .rustup
installed targets for active toolchain
--------------------------------------
i686-pc-windows-gnu
x86_64-pc-windows-gnu
x86_64-pc-windows-msvc
active toolchain
----------------
stable-x86_64-pc-windows-msvc (default)
rustc 1.45.2 (d3fb005a3 2020-07-31)
Quand j'ai fait cargo build
, j'étais en colère de ne pas pouvoir trouver x86_64-w64-mingw32-gcc. Ajoutez PATH.
PS > $ENV:Path="C:\Ruby27-x64\msys64\mingw64\bin;"+$ENV:Path
Construire.
PS addarray> cargo build --release --target=x86_64-pc-windows-gnu --verbose
Fresh addarray v0.1.0 (addarray)
Finished release [optimized] target(s) in 0.02s
addarray.dll est créé.
PS addarray> ls .\target\x86_64-pc-windows-gnu\release
annuaire: addarray\target\x86_64-pc-windows-gnu\release
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2020/09/04 --:-- .fingerprint
d----- 2020/09/04 --:-- build
d----- 2020/09/04 --:-- deps
d----- 2020/09/04 --:-- examples
d----- 2020/09/04 --:-- incremental
-a---- 2020/09/04 --:-- 0 .cargo-lock
-a---- 2020/09/04 --:-- 108 addarray.d
-a---- 2020/09/04 --:-- 3689956 addarray.dll
-a---- 2020/09/04 --:-- 2056 libaddarray.dll.a
Modifiez à nouveau la spécification DLL dans le code Ruby.
add_array_rs.rb
require 'ffi'
module AddArray
extend FFI::Library
ffi_lib 'C:\your\path\addarray\target\x86_64-pc-windows-gnu\release\addarray.dll'
attach_function :add_array, [:uint64, :uint64], :uint64
end
puts AddArray::add_array(ARGV[0].to_i, ARGV[1].to_i)
Recommended Posts