Skip to content

Instantly share code, notes, and snippets.

@naitoh
Created November 18, 2018 04:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save naitoh/08757e4bf5a6952c52f3add32370168c to your computer and use it in GitHub Desktop.
Save naitoh/08757e4bf5a6952c52f3add32370168c to your computer and use it in GitHub Desktop.
Numo::NArray vs numpy performance. (CentOS 7(x64) Ruby 2.5.3 Numo::NArray 0.9.1.3, Python 3.6.5 numpy 1.15.4)
$ cat broadcast.py
from benchmarker import Benchmarker
import numpy as np
## specify number of loop
with Benchmarker(10000, width=20) as bench:
@bench(None) ## empty loop
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
pass
@bench("z = x + y")
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
z = x + y
@bench("z = x + 1.0")
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
z = x + 1.0
@bench("z = x - y")
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
z = x - y
@bench("z = x - 1.0")
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
z = x - 1.0
@bench("z = x * y")
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
z = x * y
@bench("z = x * 1.0")
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
z = x * 1.0
@bench("z = x / y")
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
z = x / y
@bench("z = x / 1.0")
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
z = x / 1.0
$ python3.6 broadcast.py
## benchmarker: release 4.0.1 (for python)
## python version: 3.6.5
## python compiler: GCC 4.8.5 20150623 (Red Hat 4.8.5-16)
## python platform: Linux-3.10.0-514.6.1.el7.x86_64-x86_64-with-centos-7.3.1611-Core
## python executable: /usr/bin/python3.6
## cpu model: Intel(R) Core(TM) i7-4650U CPU @ 1.70GHz # 2300.090 MHz
## parameters: loop=10000, cycle=1, extra=0
## real (total = user + sys)
(Empty) 0.0022 0.0000 0.0000 0.0000
z = x + y 8.3768 8.3600 8.3300 0.0300
z = x + 1.0 6.0608 6.0600 6.0300 0.0300
z = x - y 8.5770 8.5500 8.5300 0.0200
z = x - 1.0 6.0513 6.0500 6.0400 0.0100
z = x * y 8.5377 8.5300 8.5100 0.0200
z = x * 1.0 6.1066 6.1100 6.1000 0.0100
z = x / y 8.0366 8.0300 8.0100 0.0200
z = x / 1.0 6.2885 6.2900 6.2700 0.0200
## Ranking real
z = x - 1.0 6.0513 (100.0) ********************
z = x + 1.0 6.0608 ( 99.8) ********************
z = x * 1.0 6.1066 ( 99.1) ********************
z = x / 1.0 6.2885 ( 96.2) *******************
z = x / y 8.0366 ( 75.3) ***************
z = x + y 8.3768 ( 72.2) **************
z = x * y 8.5377 ( 70.9) **************
z = x - y 8.5770 ( 70.6) **************
## Matrix real [01] [02] [03] [04] [05] [06] [07] [08]
[01] z = x - 1.0 6.0513 100.0 100.2 100.9 103.9 132.8 138.4 141.1 141.7
[02] z = x + 1.0 6.0608 99.8 100.0 100.8 103.8 132.6 138.2 140.9 141.5
[03] z = x * 1.0 6.1066 99.1 99.2 100.0 103.0 131.6 137.2 139.8 140.5
[04] z = x / 1.0 6.2885 96.2 96.4 97.1 100.0 127.8 133.2 135.8 136.4
[05] z = x / y 8.0366 75.3 75.4 76.0 78.2 100.0 104.2 106.2 106.7
[06] z = x + y 8.3768 72.2 72.4 72.9 75.1 95.9 100.0 101.9 102.4
[07] z = x * y 8.5377 70.9 71.0 71.5 73.7 94.1 98.1 100.0 100.5
[08] z = x - y 8.5770 70.6 70.7 71.2 73.3 93.7 97.7 99.5 100.0
$ cat broadcast.rb
require 'benchmark'
require 'numo/narray'
num_iteration = 10000
Benchmark.bm 20 do |r|
x = Numo::SFloat.ones([1000,784])
y = Numo::SFloat.ones([1000,784])
r.report "z = x + y" do
num_iteration.times do
z = x + y
end
end
x = Numo::SFloat.ones([1000,784])
y = Numo::SFloat.ones([1000,784])
r.report "z = x + 1.0" do
num_iteration.times do
z = x + 1.0
end
end
x = Numo::SFloat.ones([1000,784])
y = Numo::SFloat.ones([1000,784])
r.report "z = x - y" do
num_iteration.times do
z = x - y
end
end
x = Numo::SFloat.ones([1000,784])
y = Numo::SFloat.ones([1000,784])
r.report "z = x - 1.0" do
num_iteration.times do
z = x - 1.0
end
end
x = Numo::SFloat.ones([1000,784])
y = Numo::SFloat.ones([1000,784])
r.report "z = x * y" do
num_iteration.times do
z = x * y
end
end
x = Numo::SFloat.ones([1000,784])
y = Numo::SFloat.ones([1000,784])
r.report "z = x * 1.0" do
num_iteration.times do
z = x * 1.0
end
end
x = Numo::SFloat.ones([1000,784])
y = Numo::SFloat.ones([1000,784])
r.report "z = x / y" do
num_iteration.times do
z = x / y
end
end
x = Numo::SFloat.ones([1000,784])
y = Numo::SFloat.ones([1000,784])
r.report "z = x / 1.0" do
num_iteration.times do
z = x / 1.0
end
end
end
$ ruby broadcast.rb
user system total real
z = x + y 5.758811 0.803565 6.562376 ( 6.568084)
z = x + 1.0 3.424531 1.212662 4.637193 ( 4.639858)
z = x - y 5.825305 0.558036 6.383341 ( 6.402167)
z = x - 1.0 3.331074 1.031495 4.362569 ( 4.374183)
z = x * y 6.477029 2.237912 8.714941 ( 8.723648)
z = x * 1.0 3.550937 1.323607 4.874544 ( 4.882574)
z = x / y 6.101010 0.716678 6.817688 ( 6.827433)
z = x / 1.0 5.506049 1.073784 6.579833 ( 6.586551)
$ cat broadcast_inplace.py
from benchmarker import Benchmarker
import numpy as np
## specify number of loop
with Benchmarker(10000, width=20) as bench:
@bench(None) ## empty loop
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
pass
@bench("x += y")
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
x += y
@bench("x += 1.0")
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
x += 1.0
@bench("x -= y")
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
x -= y
@bench("x -= 1.0")
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
x -= 1.0
@bench("x *= y")
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
x *= y
@bench("x *= 1.0")
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
x *= 1.0
@bench("x /= y")
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
x /= y
@bench("x /= 1.0")
def _(bm):
x = np.ones([1000,784], dtype=np.float32)
y = np.ones([1000,784], dtype=np.float32)
for i in bm:
x /= 1.0
$ python3.6 broadcast_inplace.py
## benchmarker: release 4.0.1 (for python)
## python version: 3.6.5
## python compiler: GCC 4.8.5 20150623 (Red Hat 4.8.5-16)
## python platform: Linux-3.10.0-514.6.1.el7.x86_64-x86_64-with-centos-7.3.1611-Core
## python executable: /usr/bin/python3.6
## cpu model: Intel(R) Core(TM) i7-4650U CPU @ 1.70GHz # 2300.090 MHz
## parameters: loop=10000, cycle=1, extra=0
## real (total = user + sys)
(Empty) 0.0019 0.0100 0.0100 0.0000
x += y 5.5626 5.5400 5.5100 0.0300
x += 1.0 1.9940 1.9900 1.9800 0.0100
x -= y 5.6369 5.6200 5.6100 0.0100
x -= 1.0 1.9535 1.9500 1.9400 0.0100
x *= y 5.3465 5.3300 5.3300 0.0000
x *= 1.0 1.9787 1.9600 1.9600 0.0000
x /= y 5.7430 5.7300 5.7100 0.0200
x /= 1.0 5.2531 5.2500 5.2400 0.0100
## Ranking real
x -= 1.0 1.9535 (100.0) ********************
x *= 1.0 1.9787 ( 98.7) ********************
x += 1.0 1.9940 ( 98.0) ********************
x /= 1.0 5.2531 ( 37.2) *******
x *= y 5.3465 ( 36.5) *******
x += y 5.5626 ( 35.1) *******
x -= y 5.6369 ( 34.7) *******
x /= y 5.7430 ( 34.0) *******
## Matrix real [01] [02] [03] [04] [05] [06] [07] [08]
[01] x -= 1.0 1.9535 100.0 101.3 102.1 268.9 273.7 284.8 288.6 294.0
[02] x *= 1.0 1.9787 98.7 100.0 100.8 265.5 270.2 281.1 284.9 290.2
[03] x += 1.0 1.9940 98.0 99.2 100.0 263.4 268.1 279.0 282.7 288.0
[04] x /= 1.0 5.2531 37.2 37.7 38.0 100.0 101.8 105.9 107.3 109.3
[05] x *= y 5.3465 36.5 37.0 37.3 98.3 100.0 104.0 105.4 107.4
[06] x += y 5.5626 35.1 35.6 35.8 94.4 96.1 100.0 101.3 103.2
[07] x -= y 5.6369 34.7 35.1 35.4 93.2 94.8 98.7 100.0 101.9
[08] x /= y 5.7430 34.0 34.5 34.7 91.5 93.1 96.9 98.2 100.0
$ cat broadcast_inplace.rb
require 'benchmark'
require 'numo/narray'
num_iteration = 10000
Benchmark.bm 20 do |r|
x = Numo::SFloat.ones([1000,784])
y = Numo::SFloat.ones([1000,784])
r.report "x.inplace + y" do
num_iteration.times do
x.inplace + y
end
end
x = Numo::SFloat.ones([1000,784])
y = Numo::SFloat.ones([1000,784])
r.report "x.inplace + 1.0" do
num_iteration.times do
x.inplace + 1.0
end
end
x = Numo::SFloat.ones([1000,784])
y = Numo::SFloat.ones([1000,784])
r.report "x.inplace - y" do
num_iteration.times do
x.inplace - y
end
end
x = Numo::SFloat.ones([1000,784])
y = Numo::SFloat.ones([1000,784])
r.report "x.inplace - 1.0" do
num_iteration.times do
x.inplace - 1.0
end
end
x = Numo::SFloat.ones([1000,784])
y = Numo::SFloat.ones([1000,784])
r.report "x.inplace * y" do
num_iteration.times do
x.inplace * y
end
end
x = Numo::SFloat.ones([1000,784])
y = Numo::SFloat.ones([1000,784])
r.report "x.inplace * 1.0" do
num_iteration.times do
x.inplace * 1.0
end
end
x = Numo::SFloat.ones([1000,784])
y = Numo::SFloat.ones([1000,784])
r.report "x.inplace / y" do
num_iteration.times do
x.inplace / y
end
end
x = Numo::SFloat.ones([1000,784])
y = Numo::SFloat.ones([1000,784])
r.report "x.inplace / 1.0" do
num_iteration.times do
x.inplace / 1.0
end
end
end
$ ruby broadcast_inplace.rb
user system total real
x.inplace + y 5.793641 0.022095 5.815736 ( 5.821079)
x.inplace + 1.0 2.007425 0.005793 2.013218 ( 2.015859)
x.inplace - y 5.507694 0.012512 5.520206 ( 5.523620)
x.inplace - 1.0 2.053741 0.003509 2.057250 ( 2.058675)
x.inplace * y 5.582223 0.018196 5.600419 ( 5.616679)
x.inplace * 1.0 2.119237 0.004708 2.123945 ( 2.128844)
x.inplace / y 5.738079 0.011379 5.749458 ( 5.760642)
x.inplace / 1.0 5.310003 0.008684 5.318687 ( 5.327966)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment