非同期処理をすれば、もっと早くなるか?と思ったのですが、2〜2.5倍程度にしかなりません。
根本的な問題でしょうか?
また、蛇足なんですが、parralellList(Count=17)とmyList(Count=18)で、Countが異なります。 Parallel.Forで、最後の要素をAdd出来ていません。
なぜ?なんでしょうか?
詳しい方いらっしゃいましたら、ご指南頂ければと思います。
宜しくお願い致します。
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls Or SecurityProtocolType.Tls11 Or SecurityProtocolType.Tls12
Dim BaseUrl As String = "https://minkabu.jp/screening/category/5G?page="
Dim parralellList As List(Of String) = New List(Of String)()
Dim myList As List(Of String) = New List(Of String)()
'***非同期処理***
Parallel.For(1, 18, Sub(i)
Dim wc As WebClient = New WebClient With {.Encoding = Encoding.UTF8}
Dim st As System.IO.Stream = wc.OpenRead(BaseUrl & i) '1〜18
Dim parser = New AngleSharp.Html.Parser.HtmlParser()
Dim doc = parser.ParseDocument(st)
SyncLock lockTest
parralellList.Add(doc.QuerySelector("#theme > div:nth-child(3) > div.md_box.md_card.clearfix > div > div > div > table > tbody > tr:nth-child(2) > td:nth-child(1)").TextContent)
End SyncLock
End Sub)
'***同期処理***
For i As Integer = 1 To 18
Dim wc As WebClient = New WebClient With {.Encoding = Encoding.UTF8}
Dim st As System.IO.Stream = wc.OpenRead(BaseUrl & i) '1〜18
Dim parser = New AngleSharp.Html.Parser.HtmlParser()
Dim doc = parser.ParseDocument(st)
myList.Add(doc.QuerySelector("#theme > div:nth-child(3) > div.md_box.md_card.clearfix > div > div > div > table > tbody > tr:nth-child(2) > td:nth-child(1)").TextContent)
Next
■No34811に返信(Wanさんの記事)
> 教えて頂いた通り設定してみると早くなりました。
プログラムから指定する方法のほか、config で指定する方法もあります。
<system.net>
<connectionManagement>
<add address="*" maxconnection="4" />
</connectionManagement>
</system.net>
> Parallel.Forが、未満には、なんで?こんな仕様になったのか?とビックリです。
SQL の BETWEEN などは以上以下での指定となっていますが、それに対して
この手の処理では、以上未満として実装されている例が少なくないようです。
VB の場合、For ループ的にも「以下」の方が分かりやすいと感じますが、
For i As Integer = 最小値 To 最大値 Step 1
C# あるいは C 言語由来の言語系においては
for (int i = 最小値; i < 未満値; i++)
for (int i = 最小値; i <= 最大値; i++)
のように書けるのでどちらでも大差なく、
しかも実際に「未満」で指定することが多いかと思います。
どちらでも書けるなら「以下」で良いのでは…とも思えなくもないですが、
ループカウンタとしては、恐らく「未満」の方が都合が良いのでしょう。
話を簡単にするため、Integer のかわりに Byte で試してみます。
VB において、「最大値未満」とするなら、たとえば
For b As Byte = Byte.MinValue To Byte.MaxValue - 1
などのようにしますよね。(この場合、0〜254 までの 255 回ループ)
しかしこれを「最大値以下」として
For b As Byte = Byte.MinValue To Byte.MaxValue
にしたらどうなるでしょうか。
0〜255 までの 256 回ループするだけの処理…とはなりません。
コンパイラ設定にもよりますが、この結果は
『OverflowException が発生する』か、あるいは
『無限ループになって終了しない』のいずれです。
このような事情もあって、「未満」が採用されているものと想像しています。
もちろん、「以下」な作りこみにすることもできなくはないでしょうけれど、
処理としては、「未満」の方が効率が良かったのではないかと。
Index 型 / Range 型でも、末尾を含むかどうかは重要ですね。
https://docs.microsoft.com/ja-jp/dotnet/csharp/whats-new/tutorials/ranges-indexes
ご丁寧に有難う御座います。 >話を簡単にするため、Integer のかわりに Byte で試してみます。 >『OverflowException が発生する』か、あるいは >『無限ループになって終了しない』のいずれです。 を読んで昔Z80で、ループ処理をしている時に、同じような現象があった気がします。「暴走」と呼んでいましたよね? 「熱暴走」ってのもあったっけ? DEC BC LD A,B OR C みたいなの書いていたような気がします。 Zフラッグとかあったなぁ?