SlideShare a Scribd company logo
1 of 22
LINQの速度測ってみた
2019年7月19日
© 2019 Core Concept Technologies Inc.
安宅彰一朗(アタケショウイチロウ)
所属:本社事業部
役職:シニアエンジニア
好きな食べ物:ハンバーガー
最近はSpringBootでJavaJavaしてます
自己紹介
1CONFIDENTIAL
© 2019 Core Concept Technologies Inc.
ざっくり言うと集合をSQLっぽく扱える仕組みです。こんなの。
LINQとは
2CONFIDENTIAL
var ret = collection
.Where(x => x >= 500) // 条件で絞って
.Select(x => x * x) // 個別に処理して
.OrderBy(x => x); // ソートする
C#的にはIEnumerableインターフェイスを実装しているオブジェクトに
対してGenerics、拡張メソッドで実現されているライブラリです。
※ちなみにこの資料はなにか素晴らしい知見が得られるようなものではなく
思うがままLINQの速度を測ってみた、ただそれだけです!
© 2019 Core Concept Technologies Inc.
以下のようなインターフェイスです。
LINQはこれに対して処理処理を行うものです。
なのでLINQに対応した独自クラスなんかも簡単に作れちゃいます。
※今回は実装まではやりません。気になる人は実装してみてください。
IEnumerable(アイエニュメラブル)ってなんぞ?
3CONFIDENTIAL
class DemoList : IEnumerable
{
public IEnumerator GetEnumerator() { return new DemoListEnumerator(); }
class DemoListEnumerator : IEnumerator
{
public Object Current { get; } // 今いる場所
public bool MoveNext() { return true; } // 次へ移動(移動できればtrue)
public void Reset() { } // 今いる場所を最初に戻す
}
}
© 2019 Core Concept Technologies Inc.
ICollectionならプロパティあるんだから使えばいいじゃん的な
最適化が入ってますが、主要実装はこれだけ。とってもシンプル!
https://github.com/dotnet/corefx/blob/master/src/System.Linq/src/System/Linq/Count.cs
ちょっとCount覗いてみましょう
4CONFIDENTIAL
public static int Count<TSource>(this IEnumerable<TSource> source)
{
:
int count = 0;
using (IEnumerator<TSource> e = source.GetEnumerator())
{
checked
{
while (e.MoveNext())
{
count++;
}
}
}
return count;
}
© 2019 Core Concept Technologies Inc.
準備
5CONFIDENTIAL
// 1~10000000ランダム数列1億件
List<int> listRandom = SpeedTestBase.CreateList(100000000);
// 1~1億の数列
IEnumerable<int> enumerableNum = Enumerable.Range(1, 100000000);
端末スペック
CPU:Core i5(4コア)
メモリ:16GB
© 2019 Core Concept Technologies Inc.
Count-List : 00:00:00.0005399
Count-IEnumerable : 00:00:00.2788430
ListとIEnumerableのCountは全然違う
6CONFIDENTIAL
sw.Restart();
var result_01_1 = listRandom.Count();
sw.Stop();
Console.WriteLine("Count-List : " + sw.Elapsed);
sw.Restart();
var result_01_2 = enumerableNum.Count();
sw.Stop();
Console.WriteLine("Count-IEnumerable : " + sw.Elapsed);
© 2019 Core Concept Technologies Inc.
Max-LINQ : 00:00:00.6924498
Max-foreach : 00:00:00.4709000
Max(最大値)
7CONFIDENTIAL
sw.Restart();
var result_02_1 = listRandom.Max();
sw.Stop();
Console.WriteLine("Max-LINQ : " + sw.Elapsed);
sw.Restart();
int max = 0;
foreach (int i in listRandom)
{
if(max < i) { max = i; }
}
sw.Stop();
Console.WriteLine("Max-foreach : " + sw.Elapsed);
© 2019 Core Concept Technologies Inc.
Where-LINQ-toList : 00:00:00.8328413
Where-LINQ-foreach : 00:00:00.7824337
Where-foreach : 00:00:00.6183393
Where(抽出)
8CONFIDENTIAL
sw.Restart();
var result_03_1 = listRandom.Where(x => x % 123 == 0).ToList();
sw.Stop();
Console.WriteLine("Where-LINQ-toList : " + sw.Elapsed);
sw.Restart();
var result_03_2 = listRandom.Where(x => x % 123 == 0);
foreach (var x in result_03_2) { }
sw.Stop();
Console.WriteLine("Where-LINQ-foreach : " + sw.Elapsed);
sw.Restart();
var result_03_3 = new List<int>();
foreach (var x in listRandom)
{
if (x % 123 == 0)
{
result_03_3.Add(x * x);
}
}
sw.Stop();
Console.WriteLine("Where-foreach : " + sw.Elapsed);
© 2019 Core Concept Technologies Inc.
Parallel LINQ (PLINQ) は、LINQ パターンの並列実装です。 PLINQ クエリは、あらゆ
る意味において、並列ではない LINQ to Objects クエリに似ています。 PLINQ クエリ
は、LINQ の順次クエリと同様、メモリ内の IEnumerable また
は IEnumerable<T> データ ソースで実行され、遅延実行が存在するので、クエリが列
挙されるまでは実行されません。 主な相違点は、PLINQ は、システムのすべてのプロ
セッサを十分に活用しようとする点です。 そのために、データ ソースをセグメントに
パーティション分割し、複数のプロセッサで個々のワーカー スレッドの各セグメントに
対してクエリを並行実行します。 多くの場合、並行実行によって、クエリは非常に高速
に処理されます。
https://docs.microsoft.com/ja-jp/dotnet/standard/parallel-programming/parallel-
linq-plinq
そういえばPLINQってあったやん
9CONFIDENTIAL
© 2019 Core Concept Technologies Inc.
Parallel LINQ (PLINQ) は、LINQ パターンの並列実装です。 PLINQ クエリは、あらゆ
る意味において、並列ではない LINQ to Objects クエリに似ています。 PLINQ クエリ
は、LINQ の順次クエリと同様、メモリ内の IEnumerable また
は IEnumerable<T> データ ソースで実行され、遅延実行が存在するので、クエリが列
挙されるまでは実行されません。 主な相違点は、PLINQ は、システムのすべてのプロ
セッサを十分に活用しようとする点です。 そのために、データ ソースをセグメントに
パーティション分割し、複数のプロセッサで個々のワーカー スレッドの各セグメントに
対してクエリを並行実行します。 多くの場合、並行実行によって、クエリは非常に高速
に処理されます。
https://docs.microsoft.com/ja-jp/dotnet/standard/parallel-programming/parallel-
linq-plinq
そういえばPLINQってあったやん
10CONFIDENTIAL
まあ理屈はどうでもいいんですよ
測ってみましょう!
© 2019 Core Concept Technologies Inc.
PLINQ-Heavy-ForAll : 00:00:07.5491188
PLINQ-Heavy-foreach : 00:00:26.5182497
PLINQのForAllとforeach(重い処理)
11CONFIDENTIAL
sw.Restart();
var result_03_4 = listRandom.AsParallel().Where(x => x % 123 == 0);
result_03_4.ForAll(x => SpeedTestBase.HeavyProc(x));
sw.Stop();
Console.WriteLine("PLINQ-Heavy-ForAll : " + sw.Elapsed);
sw.Restart();
var result_03_5 = listRandom.AsParallel().Where(x => x % 123 == 0);
foreach(var x in result_03_5)
{
SpeedTestBase.HeavyProc(x);
}
sw.Stop();
Console.WriteLine("PLINQ-Heavy-foreach : " + sw.Elapsed);
因数分解してます
© 2019 Core Concept Technologies Inc.
Microsoftドキュメントちゃんとしてるから大好きです。
https://docs.microsoft.com/ja-jp/dotnet/standard/parallel-
programming/introduction-to-plinq
なんでなんでしたっけ?
12CONFIDENTIAL
© 2019 Core Concept Technologies Inc.
PLINQ-light-ForAll : 00:00:00.4169516
PLINQ-light-foreach : 00:00:00.3145349
PLINQのForAllとforeach(軽い処理)
13CONFIDENTIAL
sw.Restart();
var result_04_1 = listRandom.AsParallel().Where(x => x % 123 == 0);
result_04_1.ForAll(x => SpeedTestBase.lightProc(x));
sw.Stop();
Console.WriteLine("PLINQ-light-ForAll : " + sw.Elapsed);
sw.Restart();
var result_04_2 = listRandom.AsParallel().Where(x => x % 123 == 0);
foreach (var x in result_04_2)
{
SpeedTestBase.lightProc(x);
}
sw.Stop();
Console.WriteLine("PLINQ-light-foreach : " + sw.Elapsed);
1足してます
© 2019 Core Concept Technologies Inc.
学び
14CONFIDENTIAL
© 2019 Core Concept Technologies Inc.
1.PowerPointにソースコード貼るのめちゃ大変
学び
15CONFIDENTIAL
© 2019 Core Concept Technologies Inc.
1.PowerPointにソースコード貼るのめちゃ大変
2.確かにLINQはちょっと遅い、遅いけど、、、
* 読みやすい(生産性向上)
* 遅延評価(省メモリ、無限ループもいけちゃう)
* だいたい1億件ループとか業務でしないし
* 並列処理はLINQ関係なく難しい
学び
16CONFIDENTIAL
© 2019 Core Concept Technologies Inc.
1.PowerPointにソースコード貼るのめちゃ大変
2.確かにLINQはちょっと遅い、遅いけど、、、
* 読みやすい(生産性向上)
* 遅延評価(省メモリ、無限ループもいけちゃう)
* だいたい1億件ループとか業務でしないし
* 並列処理はLINQ関係なく難しい
3.でも確かに良くない書き方はあって。。。
学び
17CONFIDENTIAL
© 2019 Core Concept Technologies Inc.
やりがち1
18CONFIDENTIAL
sw.Restart();
var result_11_1 = listRandom.Where(x => x % 123 == 0).Select(x => x * x);
if(result_11_1.Count() > 0) { }
sw.Stop();
Console.WriteLine("time-11-1 : " + sw.Elapsed);
sw.Restart();
var result_11_2 = listRandom.Where(x => x % 123 == 0).Select(x => x * x);
if (result_11_2.Any()) { }
sw.Stop();
Console.WriteLine("time-11-2 : " + sw.Elapsed);
存在チェックしたいだけなのにCountしちゃう
time-11-1 : 00:00:00.6972058
time-11-2 : 00:00:00.0001552
© 2019 Core Concept Technologies Inc.
やりがち2
19CONFIDENTIAL
全部処理する必要ないのにListで受けちゃう
sw.Restart();
var result_12_1 = listRandom.Where(x => x % 123 == 0).ToList();
double sum1 = 0;
foreach (var i in result_12_1)
{
// 合計が1億超えたら終了みたいな
sum1 += i;
if (sum1 > 10000000) { break; }
}
sw.Stop();
Console.WriteLine("time-12-1 : " + sw.Elapsed);
sw.Restart();
var result_12_2 = listRandom.Where(x => x % 123 == 0);
double sum2 = 0;
foreach (var i in result_12_2)
{
// 合計が1億超えたら終了みたいな
sum2 += i;
if (sum2 > 10000000) { break; }
}
sw.Stop();
Console.WriteLine("time-12-2 : " + sw.Elapsed);
time-12-1 : 00:00:00.6682446
time-12-2 : 00:00:00.0001236
© 2019 Core Concept Technologies Inc.
やりがち3
20CONFIDENTIAL
途中まで同じなのに遅延評価しちゃう
sw.Restart();
var result_13_11 = listRandom.Where(x => x % 123 == 0).Where(x => x > 0).Count();
var result_13_12 = listRandom.Where(x => x % 123 == 0).Where(x => x > 0).Max();
var result_13_13 = listRandom.Where(x => x % 123 == 0).Where(x => x > 0).Min();
sw.Stop();
Console.WriteLine("time-13-1 : " + sw.Elapsed);
sw.Restart();
var temp = listRandom.Where(x => x % 123 == 0).Where(x => x > 0).ToList();
var result_13_21 = temp.Count();
var result_13_22 = temp.Max();
var result_13_23 = temp.Min();
sw.Stop();
Console.WriteLine("time-13-2 : " + sw.Elapsed);
time-13-1 : 00:00:02.4088091
time-13-2 : 00:00:00.8282709
Linqの速度測ってみた

More Related Content

What's hot

カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについてカスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについて
alwei
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
Moriharu Ohzu
 

What's hot (20)

ChatGPTは思ったほど賢くない
ChatGPTは思ったほど賢くないChatGPTは思ったほど賢くない
ChatGPTは思ったほど賢くない
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
 
Yahoo!ニュースにおけるBFFパフォーマンスチューニング事例
Yahoo!ニュースにおけるBFFパフォーマンスチューニング事例Yahoo!ニュースにおけるBFFパフォーマンスチューニング事例
Yahoo!ニュースにおけるBFFパフォーマンスチューニング事例
 
コールバックと戦う話
コールバックと戦う話コールバックと戦う話
コールバックと戦う話
 
Takalab 勉強会#01 - Kali Linux 環境構築
Takalab 勉強会#01 - Kali Linux 環境構築Takalab 勉強会#01 - Kali Linux 環境構築
Takalab 勉強会#01 - Kali Linux 環境構築
 
Pythonによる黒魔術入門
Pythonによる黒魔術入門Pythonによる黒魔術入門
Pythonによる黒魔術入門
 
プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜
 
UniTask入門
UniTask入門UniTask入門
UniTask入門
 
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについてカスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについて
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
 
PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。
PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。
PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。
 
ゲームAI入門(後半)
ゲームAI入門(後半)ゲームAI入門(後半)
ゲームAI入門(後半)
 
【Unity】 Behavior TreeでAIを作る
 【Unity】 Behavior TreeでAIを作る 【Unity】 Behavior TreeでAIを作る
【Unity】 Behavior TreeでAIを作る
 
Kotlinアンチパターン
KotlinアンチパターンKotlinアンチパターン
Kotlinアンチパターン
 
TOPPERSの開発も出来ちゃうVSCodeのビルド&デバッグ使いこなし術
TOPPERSの開発も出来ちゃうVSCodeのビルド&デバッグ使いこなし術TOPPERSの開発も出来ちゃうVSCodeのビルド&デバッグ使いこなし術
TOPPERSの開発も出来ちゃうVSCodeのビルド&デバッグ使いこなし術
 
オブジェクト指向プログラミングのためのモデリング入門
オブジェクト指向プログラミングのためのモデリング入門オブジェクト指向プログラミングのためのモデリング入門
オブジェクト指向プログラミングのためのモデリング入門
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
 
関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門
 
Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介
 

Similar to Linqの速度測ってみた

Handlersocket etc. 20110906
Handlersocket etc. 20110906Handlersocket etc. 20110906
Handlersocket etc. 20110906
akirahiguchi
 
ぱっと見でわかるC++11
ぱっと見でわかるC++11ぱっと見でわかるC++11
ぱっと見でわかるC++11
えぴ 福田
 
[CB19] Semzhu-Project – 手で作る組込み向けハイパーバイザと攻撃検知手法の新しい世界 by 朱義文
[CB19] Semzhu-Project – 手で作る組込み向けハイパーバイザと攻撃検知手法の新しい世界 by  朱義文[CB19] Semzhu-Project – 手で作る組込み向けハイパーバイザと攻撃検知手法の新しい世界 by  朱義文
[CB19] Semzhu-Project – 手で作る組込み向けハイパーバイザと攻撃検知手法の新しい世界 by 朱義文
CODE BLUE
 
20120405 setsunaセミナー
20120405 setsunaセミナー20120405 setsunaセミナー
20120405 setsunaセミナー
Takahiro Iwase
 
クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)
クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)
クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)
Daisuke Ikeda
 

Similar to Linqの速度測ってみた (20)

Smart Tennis Lesson Serverless Design
Smart Tennis Lesson Serverless DesignSmart Tennis Lesson Serverless Design
Smart Tennis Lesson Serverless Design
 
MlnagoyaRx
MlnagoyaRxMlnagoyaRx
MlnagoyaRx
 
Handlersocket etc. 20110906
Handlersocket etc. 20110906Handlersocket etc. 20110906
Handlersocket etc. 20110906
 
Boost17 cpplinq
Boost17 cpplinqBoost17 cpplinq
Boost17 cpplinq
 
LINQ 概要 + 結構便利な LINQ to XML
LINQ 概要 + 結構便利な LINQ to XMLLINQ 概要 + 結構便利な LINQ to XML
LINQ 概要 + 結構便利な LINQ to XML
 
Typesafe Reactive Platformで作るReactive System
Typesafe Reactive Platformで作るReactive SystemTypesafe Reactive Platformで作るReactive System
Typesafe Reactive Platformで作るReactive System
 
ぱっと見でわかるC++11
ぱっと見でわかるC++11ぱっと見でわかるC++11
ぱっと見でわかるC++11
 
TypeScriptで書くLambdaをCDKでいい感じに管理する.pptx
TypeScriptで書くLambdaをCDKでいい感じに管理する.pptxTypeScriptで書くLambdaをCDKでいい感じに管理する.pptx
TypeScriptで書くLambdaをCDKでいい感じに管理する.pptx
 
[CB19] Semzhu-Project – 手で作る組込み向けハイパーバイザと攻撃検知手法の新しい世界 by 朱義文
[CB19] Semzhu-Project – 手で作る組込み向けハイパーバイザと攻撃検知手法の新しい世界 by  朱義文[CB19] Semzhu-Project – 手で作る組込み向けハイパーバイザと攻撃検知手法の新しい世界 by  朱義文
[CB19] Semzhu-Project – 手で作る組込み向けハイパーバイザと攻撃検知手法の新しい世界 by 朱義文
 
How to Make Own Framework built on OWIN
How to Make Own Framework built on OWINHow to Make Own Framework built on OWIN
How to Make Own Framework built on OWIN
 
私たちはRESTCONFでネットワーク自動化的に何が嬉しくなるのか考えてみた
私たちはRESTCONFでネットワーク自動化的に何が嬉しくなるのか考えてみた私たちはRESTCONFでネットワーク自動化的に何が嬉しくなるのか考えてみた
私たちはRESTCONFでネットワーク自動化的に何が嬉しくなるのか考えてみた
 
20120405 setsunaセミナー
20120405 setsunaセミナー20120405 setsunaセミナー
20120405 setsunaセミナー
 
クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)
クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)
クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)
 
Hbstudy41 auto scaling
Hbstudy41 auto scalingHbstudy41 auto scaling
Hbstudy41 auto scaling
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
OSC2012-KANSAI@Kyoto JOSUG
OSC2012-KANSAI@Kyoto JOSUGOSC2012-KANSAI@Kyoto JOSUG
OSC2012-KANSAI@Kyoto JOSUG
 
運用構築技術者の為のPSプログラミング第1回
運用構築技術者の為のPSプログラミング第1回運用構築技術者の為のPSプログラミング第1回
運用構築技術者の為のPSプログラミング第1回
 
20120317 IT系勉強会 in 神戸
20120317 IT系勉強会 in 神戸20120317 IT系勉強会 in 神戸
20120317 IT系勉強会 in 神戸
 
Consulによる運用自律化体験ハンズオンとConsul活用事例紹介
Consulによる運用自律化体験ハンズオンとConsul活用事例紹介Consulによる運用自律化体験ハンズオンとConsul活用事例紹介
Consulによる運用自律化体験ハンズオンとConsul活用事例紹介
 
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
 

More from Core Concept Technologies

More from Core Concept Technologies (20)

センシングサイエンティストが経費精算を自動化したらこうなった
センシングサイエンティストが経費精算を自動化したらこうなったセンシングサイエンティストが経費精算を自動化したらこうなった
センシングサイエンティストが経費精算を自動化したらこうなった
 
コンソールアプリケーションでDIを使う
コンソールアプリケーションでDIを使うコンソールアプリケーションでDIを使う
コンソールアプリケーションでDIを使う
 
開発環境をWindowsからMacに移行してみた話
開発環境をWindowsからMacに移行してみた話開発環境をWindowsからMacに移行してみた話
開発環境をWindowsからMacに移行してみた話
 
データソースにLinqDataSourceを使った場合のGridViewの高速化
データソースにLinqDataSourceを使った場合のGridViewの高速化データソースにLinqDataSourceを使った場合のGridViewの高速化
データソースにLinqDataSourceを使った場合のGridViewの高速化
 
ロボットアームをPythonで動かす
ロボットアームをPythonで動かすロボットアームをPythonで動かす
ロボットアームをPythonで動かす
 
Pythonでディープラーニングをはじめるための一歩目
Pythonでディープラーニングをはじめるための一歩目Pythonでディープラーニングをはじめるための一歩目
Pythonでディープラーニングをはじめるための一歩目
 
Pythonで簡単動画解析
Pythonで簡単動画解析Pythonで簡単動画解析
Pythonで簡単動画解析
 
Pythonで簡単な統計・分析をしてみよう!
Pythonで簡単な統計・分析をしてみよう!Pythonで簡単な統計・分析をしてみよう!
Pythonで簡単な統計・分析をしてみよう!
 
Google Colab環境でPythonスクレイピング
Google Colab環境でPythonスクレイピングGoogle Colab環境でPythonスクレイピング
Google Colab環境でPythonスクレイピング
 
可視化の先にあるものとは
可視化の先にあるものとは可視化の先にあるものとは
可視化の先にあるものとは
 
ロボットと協働生活中に試行錯誤したこと
ロボットと協働生活中に試行錯誤したことロボットと協働生活中に試行錯誤したこと
ロボットと協働生活中に試行錯誤したこと
 
3Dモデル類似検索
3Dモデル類似検索3Dモデル類似検索
3Dモデル類似検索
 
GPUいらずの高速動画異常検知
GPUいらずの高速動画異常検知GPUいらずの高速動画異常検知
GPUいらずの高速動画異常検知
 
固有表現抽出と適用例のご紹介
固有表現抽出と適用例のご紹介固有表現抽出と適用例のご紹介
固有表現抽出と適用例のご紹介
 
深層強化学習入門
深層強化学習入門深層強化学習入門
深層強化学習入門
 
なぜIoTプロジェクトは途中でとまってしまうのか。
なぜIoTプロジェクトは途中でとまってしまうのか。なぜIoTプロジェクトは途中でとまってしまうのか。
なぜIoTプロジェクトは途中でとまってしまうのか。
 
工場に!オフィスに!明日、お安く、安全に導入できるセンサー紹介します
工場に!オフィスに!明日、お安く、安全に導入できるセンサー紹介します工場に!オフィスに!明日、お安く、安全に導入できるセンサー紹介します
工場に!オフィスに!明日、お安く、安全に導入できるセンサー紹介します
 
AIによる簡単レコメンドシステム実装
AIによる簡単レコメンドシステム実装AIによる簡単レコメンドシステム実装
AIによる簡単レコメンドシステム実装
 
Orizuru IoTは何を変えたのか
Orizuru IoTは何を変えたのかOrizuru IoTは何を変えたのか
Orizuru IoTは何を変えたのか
 
データを活用して何を実現してきたか?
データを活用して何を実現してきたか?データを活用して何を実現してきたか?
データを活用して何を実現してきたか?
 

Recently uploaded

Recently uploaded (7)

新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 

Linqの速度測ってみた

  • 2. © 2019 Core Concept Technologies Inc. 安宅彰一朗(アタケショウイチロウ) 所属:本社事業部 役職:シニアエンジニア 好きな食べ物:ハンバーガー 最近はSpringBootでJavaJavaしてます 自己紹介 1CONFIDENTIAL
  • 3. © 2019 Core Concept Technologies Inc. ざっくり言うと集合をSQLっぽく扱える仕組みです。こんなの。 LINQとは 2CONFIDENTIAL var ret = collection .Where(x => x >= 500) // 条件で絞って .Select(x => x * x) // 個別に処理して .OrderBy(x => x); // ソートする C#的にはIEnumerableインターフェイスを実装しているオブジェクトに 対してGenerics、拡張メソッドで実現されているライブラリです。 ※ちなみにこの資料はなにか素晴らしい知見が得られるようなものではなく 思うがままLINQの速度を測ってみた、ただそれだけです!
  • 4. © 2019 Core Concept Technologies Inc. 以下のようなインターフェイスです。 LINQはこれに対して処理処理を行うものです。 なのでLINQに対応した独自クラスなんかも簡単に作れちゃいます。 ※今回は実装まではやりません。気になる人は実装してみてください。 IEnumerable(アイエニュメラブル)ってなんぞ? 3CONFIDENTIAL class DemoList : IEnumerable { public IEnumerator GetEnumerator() { return new DemoListEnumerator(); } class DemoListEnumerator : IEnumerator { public Object Current { get; } // 今いる場所 public bool MoveNext() { return true; } // 次へ移動(移動できればtrue) public void Reset() { } // 今いる場所を最初に戻す } }
  • 5. © 2019 Core Concept Technologies Inc. ICollectionならプロパティあるんだから使えばいいじゃん的な 最適化が入ってますが、主要実装はこれだけ。とってもシンプル! https://github.com/dotnet/corefx/blob/master/src/System.Linq/src/System/Linq/Count.cs ちょっとCount覗いてみましょう 4CONFIDENTIAL public static int Count<TSource>(this IEnumerable<TSource> source) { : int count = 0; using (IEnumerator<TSource> e = source.GetEnumerator()) { checked { while (e.MoveNext()) { count++; } } } return count; }
  • 6. © 2019 Core Concept Technologies Inc. 準備 5CONFIDENTIAL // 1~10000000ランダム数列1億件 List<int> listRandom = SpeedTestBase.CreateList(100000000); // 1~1億の数列 IEnumerable<int> enumerableNum = Enumerable.Range(1, 100000000); 端末スペック CPU:Core i5(4コア) メモリ:16GB
  • 7. © 2019 Core Concept Technologies Inc. Count-List : 00:00:00.0005399 Count-IEnumerable : 00:00:00.2788430 ListとIEnumerableのCountは全然違う 6CONFIDENTIAL sw.Restart(); var result_01_1 = listRandom.Count(); sw.Stop(); Console.WriteLine("Count-List : " + sw.Elapsed); sw.Restart(); var result_01_2 = enumerableNum.Count(); sw.Stop(); Console.WriteLine("Count-IEnumerable : " + sw.Elapsed);
  • 8. © 2019 Core Concept Technologies Inc. Max-LINQ : 00:00:00.6924498 Max-foreach : 00:00:00.4709000 Max(最大値) 7CONFIDENTIAL sw.Restart(); var result_02_1 = listRandom.Max(); sw.Stop(); Console.WriteLine("Max-LINQ : " + sw.Elapsed); sw.Restart(); int max = 0; foreach (int i in listRandom) { if(max < i) { max = i; } } sw.Stop(); Console.WriteLine("Max-foreach : " + sw.Elapsed);
  • 9. © 2019 Core Concept Technologies Inc. Where-LINQ-toList : 00:00:00.8328413 Where-LINQ-foreach : 00:00:00.7824337 Where-foreach : 00:00:00.6183393 Where(抽出) 8CONFIDENTIAL sw.Restart(); var result_03_1 = listRandom.Where(x => x % 123 == 0).ToList(); sw.Stop(); Console.WriteLine("Where-LINQ-toList : " + sw.Elapsed); sw.Restart(); var result_03_2 = listRandom.Where(x => x % 123 == 0); foreach (var x in result_03_2) { } sw.Stop(); Console.WriteLine("Where-LINQ-foreach : " + sw.Elapsed); sw.Restart(); var result_03_3 = new List<int>(); foreach (var x in listRandom) { if (x % 123 == 0) { result_03_3.Add(x * x); } } sw.Stop(); Console.WriteLine("Where-foreach : " + sw.Elapsed);
  • 10. © 2019 Core Concept Technologies Inc. Parallel LINQ (PLINQ) は、LINQ パターンの並列実装です。 PLINQ クエリは、あらゆ る意味において、並列ではない LINQ to Objects クエリに似ています。 PLINQ クエリ は、LINQ の順次クエリと同様、メモリ内の IEnumerable また は IEnumerable<T> データ ソースで実行され、遅延実行が存在するので、クエリが列 挙されるまでは実行されません。 主な相違点は、PLINQ は、システムのすべてのプロ セッサを十分に活用しようとする点です。 そのために、データ ソースをセグメントに パーティション分割し、複数のプロセッサで個々のワーカー スレッドの各セグメントに 対してクエリを並行実行します。 多くの場合、並行実行によって、クエリは非常に高速 に処理されます。 https://docs.microsoft.com/ja-jp/dotnet/standard/parallel-programming/parallel- linq-plinq そういえばPLINQってあったやん 9CONFIDENTIAL
  • 11. © 2019 Core Concept Technologies Inc. Parallel LINQ (PLINQ) は、LINQ パターンの並列実装です。 PLINQ クエリは、あらゆ る意味において、並列ではない LINQ to Objects クエリに似ています。 PLINQ クエリ は、LINQ の順次クエリと同様、メモリ内の IEnumerable また は IEnumerable<T> データ ソースで実行され、遅延実行が存在するので、クエリが列 挙されるまでは実行されません。 主な相違点は、PLINQ は、システムのすべてのプロ セッサを十分に活用しようとする点です。 そのために、データ ソースをセグメントに パーティション分割し、複数のプロセッサで個々のワーカー スレッドの各セグメントに 対してクエリを並行実行します。 多くの場合、並行実行によって、クエリは非常に高速 に処理されます。 https://docs.microsoft.com/ja-jp/dotnet/standard/parallel-programming/parallel- linq-plinq そういえばPLINQってあったやん 10CONFIDENTIAL まあ理屈はどうでもいいんですよ 測ってみましょう!
  • 12. © 2019 Core Concept Technologies Inc. PLINQ-Heavy-ForAll : 00:00:07.5491188 PLINQ-Heavy-foreach : 00:00:26.5182497 PLINQのForAllとforeach(重い処理) 11CONFIDENTIAL sw.Restart(); var result_03_4 = listRandom.AsParallel().Where(x => x % 123 == 0); result_03_4.ForAll(x => SpeedTestBase.HeavyProc(x)); sw.Stop(); Console.WriteLine("PLINQ-Heavy-ForAll : " + sw.Elapsed); sw.Restart(); var result_03_5 = listRandom.AsParallel().Where(x => x % 123 == 0); foreach(var x in result_03_5) { SpeedTestBase.HeavyProc(x); } sw.Stop(); Console.WriteLine("PLINQ-Heavy-foreach : " + sw.Elapsed); 因数分解してます
  • 13. © 2019 Core Concept Technologies Inc. Microsoftドキュメントちゃんとしてるから大好きです。 https://docs.microsoft.com/ja-jp/dotnet/standard/parallel- programming/introduction-to-plinq なんでなんでしたっけ? 12CONFIDENTIAL
  • 14. © 2019 Core Concept Technologies Inc. PLINQ-light-ForAll : 00:00:00.4169516 PLINQ-light-foreach : 00:00:00.3145349 PLINQのForAllとforeach(軽い処理) 13CONFIDENTIAL sw.Restart(); var result_04_1 = listRandom.AsParallel().Where(x => x % 123 == 0); result_04_1.ForAll(x => SpeedTestBase.lightProc(x)); sw.Stop(); Console.WriteLine("PLINQ-light-ForAll : " + sw.Elapsed); sw.Restart(); var result_04_2 = listRandom.AsParallel().Where(x => x % 123 == 0); foreach (var x in result_04_2) { SpeedTestBase.lightProc(x); } sw.Stop(); Console.WriteLine("PLINQ-light-foreach : " + sw.Elapsed); 1足してます
  • 15. © 2019 Core Concept Technologies Inc. 学び 14CONFIDENTIAL
  • 16. © 2019 Core Concept Technologies Inc. 1.PowerPointにソースコード貼るのめちゃ大変 学び 15CONFIDENTIAL
  • 17. © 2019 Core Concept Technologies Inc. 1.PowerPointにソースコード貼るのめちゃ大変 2.確かにLINQはちょっと遅い、遅いけど、、、 * 読みやすい(生産性向上) * 遅延評価(省メモリ、無限ループもいけちゃう) * だいたい1億件ループとか業務でしないし * 並列処理はLINQ関係なく難しい 学び 16CONFIDENTIAL
  • 18. © 2019 Core Concept Technologies Inc. 1.PowerPointにソースコード貼るのめちゃ大変 2.確かにLINQはちょっと遅い、遅いけど、、、 * 読みやすい(生産性向上) * 遅延評価(省メモリ、無限ループもいけちゃう) * だいたい1億件ループとか業務でしないし * 並列処理はLINQ関係なく難しい 3.でも確かに良くない書き方はあって。。。 学び 17CONFIDENTIAL
  • 19. © 2019 Core Concept Technologies Inc. やりがち1 18CONFIDENTIAL sw.Restart(); var result_11_1 = listRandom.Where(x => x % 123 == 0).Select(x => x * x); if(result_11_1.Count() > 0) { } sw.Stop(); Console.WriteLine("time-11-1 : " + sw.Elapsed); sw.Restart(); var result_11_2 = listRandom.Where(x => x % 123 == 0).Select(x => x * x); if (result_11_2.Any()) { } sw.Stop(); Console.WriteLine("time-11-2 : " + sw.Elapsed); 存在チェックしたいだけなのにCountしちゃう time-11-1 : 00:00:00.6972058 time-11-2 : 00:00:00.0001552
  • 20. © 2019 Core Concept Technologies Inc. やりがち2 19CONFIDENTIAL 全部処理する必要ないのにListで受けちゃう sw.Restart(); var result_12_1 = listRandom.Where(x => x % 123 == 0).ToList(); double sum1 = 0; foreach (var i in result_12_1) { // 合計が1億超えたら終了みたいな sum1 += i; if (sum1 > 10000000) { break; } } sw.Stop(); Console.WriteLine("time-12-1 : " + sw.Elapsed); sw.Restart(); var result_12_2 = listRandom.Where(x => x % 123 == 0); double sum2 = 0; foreach (var i in result_12_2) { // 合計が1億超えたら終了みたいな sum2 += i; if (sum2 > 10000000) { break; } } sw.Stop(); Console.WriteLine("time-12-2 : " + sw.Elapsed); time-12-1 : 00:00:00.6682446 time-12-2 : 00:00:00.0001236
  • 21. © 2019 Core Concept Technologies Inc. やりがち3 20CONFIDENTIAL 途中まで同じなのに遅延評価しちゃう sw.Restart(); var result_13_11 = listRandom.Where(x => x % 123 == 0).Where(x => x > 0).Count(); var result_13_12 = listRandom.Where(x => x % 123 == 0).Where(x => x > 0).Max(); var result_13_13 = listRandom.Where(x => x % 123 == 0).Where(x => x > 0).Min(); sw.Stop(); Console.WriteLine("time-13-1 : " + sw.Elapsed); sw.Restart(); var temp = listRandom.Where(x => x % 123 == 0).Where(x => x > 0).ToList(); var result_13_21 = temp.Count(); var result_13_22 = temp.Max(); var result_13_23 = temp.Min(); sw.Stop(); Console.WriteLine("time-13-2 : " + sw.Elapsed); time-13-1 : 00:00:02.4088091 time-13-2 : 00:00:00.8282709