Schreiben Sie Ruby-Methoden mit C ++ (Teil 2) Benchmark

Inhaltsverzeichnis

Schreiben von Ruby-Methoden mit C ++ (Teil 1) Schreiben Sie Ruby-Methoden mit C ++ (Teil 2) Benchmark <-Hier

Benchmark

Ein einfaches Programm, das die Summe eines Arrays berechnet. Mit der in Teil 1 oben beschriebenen Methode (1) Ich habe die Geschwindigkeiten von Ruby-Methoden mit C (Teil 2) Numo :: NArray schreiben (2) verglichen. Beim Übergeben von Numo :: SFloat-Typdaten (3) (berechnet nach dem Casting an Numo :: DFloat) Nach der Konvertierung von NArray in Array wird dieselbe Methode wie in (1) (4) angewendet. Nach der Konvertierung von Array in Numo :: DFloat wird dieselbe Methode wie in (2) (5) verwendet. Verwendung der in Ruby integrierten Funktion Array # sum (6), Verwendung der in Ruby integrierten Funktion Array # injizieren (7), Verwendung der Numo :: DFloat-Funktionssumme (8) Vergleichen die Geschwindigkeiten von.

Das Ergebnis wird am Ende geschrieben.

Methode 1 (1) ist schnell genug, aber Methode (2) ist die schnellste. Array # sum in (6) ist ziemlich schnell und Ruby-Funktionen, die binär geschrieben sind, können in ihrer Geschwindigkeit erwartet werden. Ich bin der Meinung, dass die Summe von Numo :: DFloat # unerwartet langsam ist und die Konvertierung von Array zu Numo :: DFloat ebenfalls langsam ist.

Programm verwendet

test.cpp


#include "test.hpp"

double sum(const std::vector<double>& ary){
    double sum=0.0;
    for (int i=0; i<ary.size(); i++){
        sum+=ary[i];
    }
    return(sum);
}

double sum_nd(int n, double *ary){
    double sum=0.0;
    for (int i=0; i<n; i++){
        sum+=ary[i];
    }
    return(sum);
}

test.hpp


#include <vector>
double sum(const std::vector<double>& ary);
double sum_nd(int n, double *ary);

test.i


%module testF
%{
#include "numo/narray.h"
#include "test.hpp"
%}

%include <std_vector.i>
%template(DoubleVector) std::vector<double>;
extern double sum(std::vector<double> ary);

%typemap(in) (int LENGTH, double *NARRAY_in){
  narray_t *nary;
  if (rb_obj_class($input)!=numo_cDFloat){
      $input = rb_funcall(numo_cDFloat, rb_intern("cast"), 1, $input);
  }
  GetNArray($input, nary);
  if (NA_TYPE(nary)==NARRAY_VIEW_T){
    $input = rb_funcall($input, rb_intern("dup"), 0);
    GetNArray($input, nary);
  }
  $2 = ($2_ltype)na_get_pointer_for_read($input);
  $1 = NA_SIZE(nary);
}
extern double sum_nd(int LENGTH, double *NARRAY_in);

extconf.rb


require 'mkmf'
dir_config("numo/narray")
have_header("numo/narray.h")
create_makefile("testF")
swig -c++ -ruby test.i
ruby extconf.rb  -- --with-numo/narray-include=/opt/lib/ruby/gems/2.6.0/gems/numo-narray-0.9.1.8/lib/numo/
make

Bankprogramm

benchmark.rb


require "benchmark"
require "numo/narray"
require "./testF"

data=[*1..100].map(&:to_f)
data_na=Numo::DFloat.cast(data)
data_naf=Numo::SFloat.cast(data)

puts Benchmark::CAPTION
puts Benchmark.measure{
	1000000.times{
		TestF::sum(data) # (1)
	}
}
=begin
Weniger als
TestF::sum_nd(data_na)   # (2)
TestF::sum_nd(data_naf)  # (3)
TestF::sum(data_na.to_a) # (4)
TestF::sum_nd(Numo::DFloat.cast(data)) # (5)
data.sum                 # (6)
data.inject(:+)          # (7)
data_na.sum              # (8)
=end

Ergebnis

Datenfluss Ausführungszeit(μs)
(1) Array => vector 2.44
(2) Numo::DFloat => double [] 0.14
(3) Numo::SFloat => cast -> double [] 1.59
(4) Numo::DFloat -> Array => vector 4.77
(5) Array -> Numo::DFloat => double [] 10.11
(6) Array#sum 0.60
(7) Array#inject(:+) 3.42
(8) Numo::DFloat#sum 1.30

(Die Ausführungszeit wird in eine Schleife umgewandelt.)

Recommended Posts

Schreiben Sie Ruby-Methoden mit C ++ (Teil 2) Benchmark
Schreiben Sie Ruby-Methoden mit C (Teil 1)
Schreiben Sie Ruby-Methoden mit C (Numo :: NArray)
Schreiben Sie Code mit Ruby-Klassen und -Instanzen
Über Ruby-Methoden
Versuchen Sie es mit der Methode java.lang.Math
Versuchen Sie es mit Talend Teil 2
Informationen zu Ruby-Instanzmethoden
Versuchen Sie es mit Talend Teil 1
[Ruby] -Methode, Instanzmethode ...
Ich habe einen C-Parser (wie) mit PEG in Ruby geschrieben
Lösen mit Ruby, Perl und Java AtCoder ABC 129 C (Teil 1)