scala 下 sigmoid 与breeze.numeric.sigmoid差异对比

scala>     val beforeInit = System.nanoTime;val handsgn = rd.map(x => 1.0 / (1.0 + Math.exp(-x)));val cost = System.nanoTime - beforeInit;
beforeInit: Long = 35022621366051878
handsgn: scala.collection.immutable.IndexedSeq[Double] = Vector(0.6666755488429456, 0.6787806786393414, 0.6529507380367386, 0.6808414264302959, 0.5888748381101, 0.6206479525547044, 0.5472020814143724, 0.5753974761545867, 0.5587867292203849, 0.5063225260538604, 0.6904543881882752, 0.5606615580952308, 0.6879474616785335, 0.6145848916214701, 0.5044123510408592, 0.5960397224312342, 0.7101654507649577, 0.6918354450622388, 0.5142539384969489, 0.6753761634399785, 0.5981233179292798, 0.5789215904180679, 0.7023174432239545, 0.5710123819509948, 0.5088592463935145, 0.682943856507884, 0.7109637098283254, 0.639949076321439, 0.5695993566470937, 0.5109011361739307, 0.5053771358846573, 0.6872196495199817, 0.62922618014367, 0.6113402049344542, 0.6518850736815989, 0.5...
scala>     val beforeInit = System.nanoTime;val handsgn = rd.map(x => 1.0 / (1.0 + Math.exp(-x)));println(System.nanoTime - beforeInit);
1771465
beforeInit: Long = 35022633234799178
handsgn: scala.collection.immutable.IndexedSeq[Double] = Vector(0.6666755488429456, 0.6787806786393414, 0.6529507380367386, 0.6808414264302959, 0.5888748381101, 0.6206479525547044, 0.5472020814143724, 0.5753974761545867, 0.5587867292203849, 0.5063225260538604, 0.6904543881882752, 0.5606615580952308, 0.6879474616785335, 0.6145848916214701, 0.5044123510408592, 0.5960397224312342, 0.7101654507649577, 0.6918354450622388, 0.5142539384969489, 0.6753761634399785, 0.5981233179292798, 0.5789215904180679, 0.7023174432239545, 0.5710123819509948, 0.5088592463935145, 0.682943856507884, 0.7109637098283254, 0.639949076321439, 0.5695993566470937, 0.5109011361739307, 0.5053771358846573, 0.6872196495199817, 0.62922618014367, 0.6113402049344542, 0.6518850736815989, 0.5...
scala>     val beforeInit = System.nanoTime;val handsgn = rd.map(x => breeze.numerics.sigmoid(x));println(System.nanoTime - beforeInit);
1912128
beforeInit: Long = 35022662283025264
handsgn: scala.collection.immutable.IndexedSeq[Double] = Vector(0.6666755488429456, 0.6787806786393414, 0.6529507380367386, 0.6808414264302959, 0.5888748381101, 0.6206479525547044, 0.5472020814143724, 0.5753974761545867, 0.5587867292203849, 0.5063225260538604, 0.6904543881882752, 0.5606615580952308, 0.6879474616785335, 0.6145848916214701, 0.5044123510408592, 0.5960397224312342, 0.7101654507649577, 0.6918354450622388, 0.5142539384969489, 0.6753761634399785, 0.5981233179292798, 0.5789215904180679, 0.7023174432239545, 0.5710123819509948, 0.5088592463935145, 0.682943856507884, 0.7109637098283254, 0.639949076321439, 0.5695993566470937, 0.5109011361739307, 0.5053771358846573, 0.6872196495199817, 0.62922618014367, 0.6113402049344542, 0.6518850736815989, 0.5...
scala> Display all 675 possibilities? (y or n)xtDouble)
scala> val rd = (0 until 20000).map(i => rand.nextDouble)
rd: scala.collection.immutable.IndexedSeq[Double] = Vector(0.12850502397540942, 0.3800041327418344, 0.8536607295833647, 0.9821419704320834, 0.9938382163394424, 0.7708907441645584, 0.4612756601796696, 0.9371991197262541, 0.5184642043060644, 0.3427131854754534, 0.6524428612208136, 0.3653548619699837, 0.2500488616933274, 0.3845525940247323, 0.7905273172914156, 0.6233163882696882, 0.372006158200208, 0.8347691893470309, 0.5578402978215722, 0.03409879025840201, 0.6124513832158451, 0.3294679930932689, 0.3043858000267232, 0.9841288626829339, 0.21286344025656612, 0.37437105411110394, 0.2746904891571903, 0.11215396563509472, 0.5582924876697188, 0.5361226069230965, 0.623635777327592, 0.18959661621427737, 0.5094273476465386, 0.08909292800046442, 0.33631329890983075, 0.2226581701432716, 0.6965624230...
scala>     val beforeInit = System.nanoTime;val handsgn = rd.map(x => 1.0 / (1.0 + Math.exp(-x)));println(System.nanoTime - beforeInit);
5988031
beforeInit: Long = 35023297370957812
handsgn: scala.collection.immutable.IndexedSeq[Double] = Vector(0.5320821190238922, 0.5938740997008346, 0.7013344997792978, 0.7275330232805813, 0.729845374992795, 0.6837135480806683, 0.6133167545291345, 0.7185335456160364, 0.6267885758448689, 0.5848494372094519, 0.6575607445298361, 0.590336074284138, 0.5621885273773267, 0.5949706623004747, 0.687944544614549, 0.6509724330457866, 0.5919436478913106, 0.6973624044695454, 0.635952679757521, 0.508523871668941, 0.6484997927293775, 0.5816299257386118, 0.5755143104336967, 0.7279267042885952, 0.5530158284135527, 0.5925147554574627, 0.5682440488414993, 0.5280091381218828, 0.6360573628979685, 0.6309099771887011, 0.6510449970795169, 0.5472576749753335, 0.6246722217973547, 0.5222585107776622, 0.5832947021280129, 0...
scala>     val beforeInit = System.nanoTime;val handsgn = rd.map(x => breeze.numerics.sigmoid(x));println(System.nanoTime - beforeInit);
7606556
beforeInit: Long = 35023300754974325
handsgn: scala.collection.immutable.IndexedSeq[Double] = Vector(0.5320821190238922, 0.5938740997008346, 0.7013344997792978, 0.7275330232805813, 0.729845374992795, 0.6837135480806683, 0.6133167545291345, 0.7185335456160364, 0.6267885758448689, 0.5848494372094519, 0.6575607445298361, 0.590336074284138, 0.5621885273773267, 0.5949706623004747, 0.687944544614549, 0.6509724330457866, 0.5919436478913106, 0.6973624044695454, 0.635952679757521, 0.508523871668941, 0.6484997927293775, 0.5816299257386118, 0.5755143104336967, 0.7279267042885952, 0.5530158284135527, 0.5925147554574627, 0.5682440488414993, 0.5280091381218828, 0.6360573628979685, 0.6309099771887011, 0.6510449970795169, 0.5472576749753335, 0.6246722217973547, 0.5222585107776622, 0.5832947021280129, 0...

综上试验,直接编写公式,速度相比调用breeze库,时间更短,开销更小。

scala> def sig(x: Double): Double = 1.0 / (1.0 + Math.exp(-x))
sig: (x: Double)Double

scala>     val beforeInit = System.nanoTime;val handsgn = rd.map(x => sig(x));println(System.nanoTime - beforeInit);
9380656
beforeInit: Long = 35023440728477327
handsgn: scala.collection.immutable.IndexedSeq[Double] = Vector(0.5320821190238922, 0.5938740997008346, 0.7013344997792978, 0.7275330232805813, 0.729845374992795, 0.6837135480806683, 0.6133167545291345, 0.7185335456160364, 0.6267885758448689, 0.5848494372094519, 0.6575607445298361, 0.590336074284138, 0.5621885273773267, 0.5949706623004747, 0.687944544614549, 0.6509724330457866, 0.5919436478913106, 0.6973624044695454, 0.635952679757521, 0.508523871668941, 0.6484997927293775, 0.5816299257386118, 0.5755143104336967, 0.7279267042885952, 0.5530158284135527, 0.5925147554574627, 0.5682440488414993, 0.5280091381218828, 0.6360573628979685, 0.6309099771887011, 0.6510449970795169, 0.5472576749753335, 0.6246722217973547, 0.5222585107776622, 0.5832947021280129, 0...
scala>     val beforeInit = System.nanoTime;val handsgn = rd.map(x => breeze.numerics.sigmoid(x));println(System.nanoTime - beforeInit);
7435700
beforeInit: Long = 35023447719287935
handsgn: scala.collection.immutable.IndexedSeq[Double] = Vector(0.5320821190238922, 0.5938740997008346, 0.7013344997792978, 0.7275330232805813, 0.729845374992795, 0.6837135480806683, 0.6133167545291345, 0.7185335456160364, 0.6267885758448689, 0.5848494372094519, 0.6575607445298361, 0.590336074284138, 0.5621885273773267, 0.5949706623004747, 0.687944544614549, 0.6509724330457866, 0.5919436478913106, 0.6973624044695454, 0.635952679757521, 0.508523871668941, 0.6484997927293775, 0.5816299257386118, 0.5755143104336967, 0.7279267042885952, 0.5530158284135527, 0.5925147554574627, 0.5682440488414993, 0.5280091381218828, 0.6360573628979685, 0.6309099771887011, 0.6510449970795169, 0.5472576749753335, 0.6246722217973547, 0.5222585107776622, 0.5832947021280129, 0...
scala>     val beforeInit = System.nanoTime;val handsgn = rd.map(x => 1.0 / (1.0 + Math.exp(-x)));println(System.nanoTime - beforeInit);
6011454
beforeInit: Long = 35023455808772793
handsgn: scala.collection.immutable.IndexedSeq[Double] = Vector(0.5320821190238922, 0.5938740997008346, 0.7013344997792978, 0.7275330232805813, 0.729845374992795, 0.6837135480806683, 0.6133167545291345, 0.7185335456160364, 0.6267885758448689, 0.5848494372094519, 0.6575607445298361, 0.590336074284138, 0.5621885273773267, 0.5949706623004747, 0.687944544614549, 0.6509724330457866, 0.5919436478913106, 0.6973624044695454, 0.635952679757521, 0.508523871668941, 0.6484997927293775, 0.5816299257386118, 0.5755143104336967, 0.7279267042885952, 0.5530158284135527, 0.5925147554574627, 0.5682440488414993, 0.5280091381218828, 0.6360573628979685, 0.6309099771887011, 0.6510449970795169, 0.5472576749753335, 0.6246722217973547, 0.5222585107776622, 0.5832947021280129, 0...

scala> new breeze.linalg.DenseVector(rd.toArray)
res21: breeze.linalg.DenseVector[Double] = DenseVector(0.12850502397540942, 0.3800041327418344, 0.8536607295833647, 0.9821419704320834, 0.9938382163394424, 0.7708907441645584, 0.4612756601796696, 0.9371991197262541, 0.5184642043060644, 0.3427131854754534, 0.6524428612208136, 0.3653548619699837, 0.2500488616933274, 0.3845525940247323, 0.7905273172914156, 0.6233163882696882, 0.372006158200208, 0.8347691893470309, 0.5578402978215722, 0.03409879025840201, 0.6124513832158451, 0.3294679930932689, 0.3043858000267232, 0.9841288626829339, 0.21286344025656612, 0.37437105411110394, 0.2746904891571903, 0.11215396563509472, 0.5582924876697188, 0.5361226069230965, 0.623635777327592, 0.18959661621427737, 0.5094273476465386, 0.08909292800046442, 0.33631329890983075, 0.2226581701432716, 0.69656242309717...
scala>     val beforeInit = System.nanoTime;breeze.numerics.sigmoid(res21);println(System.nanoTime - beforeInit);
3372600
beforeInit: Long = 35024279429434608


scala>     val beforeInit = System.nanoTime;breeze.numerics.sigmoid(new breeze.linalg.DenseVector(rd.toArray));println(System.nanoTime - beforeInit);
4293909
beforeInit: Long = 35024437699054802

本次试验,证明在有函数调用的情况下,开销有较大上升。
时间开销分别:handFomula < breeze.numeric < funcDef。
值得注意的是,当将20000个实数组织成Vector形式进行计算时,breeze有了极大的性能提升。基本可以将时间开销降低到先前一半的水平。即便是包含Vector组织的时间开销,依然在计算时间上有较大优势。
并且在20、200、2000、20000条样本的测试下,breeze有着几乎等比例提升。

综上:当计算数据为数字或者数值变量,在不影响逻辑和可读性的情况下,尽量将公式操作以代码形式写入逻辑。
但当出现对向量、矩阵进行操作,抑或者对大量数值同时计算,建议通过线性库适当调整形式,进而借用线性库的加速特性,提高程序运行效率。

猜你喜欢

转载自www.cnblogs.com/suanec/p/9997712.html