I was profiling an application that does a lot of math operations on NMatrix matrices.
The application spends most of it's time in in the code below.
{add: :+, sub: :-, mul: :*, div: :/, pow: :**, mod: :%}.each_pair do |ewop, op|
define_method("__list_elementwise_#{ewop}__") do |rhs|
self.__list_map_merged_stored__(rhs, nil) { |l,r| l.send(op,r) }.cast(stype, NMatrix.upcast(dtype, rhs.dtype))
end
define_method("__dense_elementwise_#{ewop}__") do |rhs|
self.__dense_map_pair__(rhs) { |l,r| l.send(op,r) }.cast(stype, NMatrix.upcast(dtype, rhs.dtype))
end
define_method("__yale_elementwise_#{ewop}__") do |rhs|
self.__yale_map_merged_stored__(rhs, nil) { |l,r| l.send(op,r) }.cast(stype, NMatrix.upcast(dtype, rhs.dtype))
end
end
In the commets above the code it says:
# Define the element-wise operations for lists. Note that the __list_map_merged_stored__ iterator returns a Ruby Object
# matrix, which we then cast back to the appropriate type. If you don't want that, you can redefine these functions in
# your own code.
I am not that familiar with the internals of NMatrix but it seems as though the math operations are being executed in Ruby. Is there anyway to speed up these methods?
We had written them in C/C++ originally, but it required some really complicated macros which were basically unmaintainable and buggy, and substantially increased compile time.
If you look in
History.txt
, you'll be able to find at what version we started writing the math operations in Ruby. You could use the prior code to override and put the element-wise operations (where you need speed) exclusively in C/C++.However, you may run into problems getting those to work properly (without a crash) on matrices of dtype
:object
.As a side note, the sciruby-dev Google Group (or the nmatrix issue tracker) might be a more appropriate place for a question like this one.