DOBON.NETプログラミング道掲示板

■34797 / 親記事)   Parallel.Forで思ったより早くならない
  
□投稿者/ Wan 一般人(23回)-(2021/06/28(Mon) 17:25:06)
  • アイコン環境/言語:[Windows10 VisualStudio2019 VB.net WindowsForm] 
    分類:[.NET] 

    非同期処理をすれば、もっと早くなるか?と思ったのですが、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

マルチポストを報告
違反を報告
引用返信 削除キー/
■34801 / ResNo.1)  Re[1]: Parallel.Forで思ったより早くならない
□投稿者/ 魔界の仮面弁士 大御所(1360回)-(2021/06/28(Mon) 19:44:26)
  • アイコンNo34797に返信(Wanさんの記事)
    > Dim BaseUrl As String = "https://minkabu.jp/screening/category/5G?page="

    みんかぶは利用規約 第7条 第18項により、非公認プログラムによる
    収集行為(スクレイピング)が制限されています。
    規約違反とならぬようご注意ください。
    https://info.minkabu.jp/terms/


    > 非同期処理をすれば、もっと早くなるか?と思ったのですが、2〜2.5倍程度にしかなりません。
    > 根本的な問題でしょうか?

    ServicePointManager.DefaultConnectionLimit の既定値は 2 に設定されています。

    HTTP 1.1 においては、RFC2616 によって、同時接続数の上限を 2 にすることが
    推奨されているためです。一つのクライアントが、同じサーバーに対して
    多数の接続を張ってしまうと、他者に迷惑をかけてしまいますからね。
    https://www.atmarkit.co.jp/fwin2k/win2ktips/1064maxhttp/maxhttp.html


    > また、蛇足なんですが、parralellList(Count=17)とmyList(Count=18)で、Countが異なります。
    Parallel.For の引数は「以上・以下」ではなく「以上・未満」の指定だからです。
    Random クラスの Next メソッドもそうですよね。
違反を報告
引用返信 削除キー/
■34811 / ResNo.2)  Re[2]: Parallel.Forで思ったより早くならない
□投稿者/ Wan 一般人(25回)-(2021/07/01(Thu) 11:43:43)
  • アイコンお返事が遅くなり申し訳ございません。

    教えて頂いた通り設定してみると早くなりました。

    Parallel.Forが、未満には、なんで?こんな仕様になったのか?とビックリです。
    マイクロソフトのドキュメント読むと確かにそう書いてありました。
    が、見落としてしまうなぁ?

    有難う御座いました。
違反を報告
引用返信 削除キー/
■34812 / ResNo.3)  Re[3]: Parallel.Forで思ったより早くならない
□投稿者/ Wan 一般人(28回)-(2021/07/01(Thu) 11:46:09)
  • アイコン解決済みを押し忘れました。
解決み!
違反を報告
引用返信 削除キー/
■34814 / ResNo.4)  Re[3]: Parallel.Forで思ったより早くならない
□投稿者/ 魔界の仮面弁士 大御所(1366回)-(2021/07/01(Thu) 13:45:10)
  • アイコン
    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

解決み!
違反を報告
引用返信 削除キー/
■34816 / ResNo.5)  Re[4]: Parallel.Forで思ったより早くならない
□投稿者/ Wan 一般人(29回)-(2021/07/02(Fri) 07:11:59)
  • アイコンご丁寧に有難う御座います。
    >話を簡単にするため、Integer のかわりに Byte で試してみます。
    >『OverflowException が発生する』か、あるいは
    >『無限ループになって終了しない』のいずれです。
    を読んで昔Z80で、ループ処理をしている時に、同じような現象があった気がします。「暴走」と呼んでいましたよね?
    「熱暴走」ってのもあったっけ?
    DEC BC
    LD A,B
    OR C
    みたいなの書いていたような気がします。
    Zフラッグとかあったなぁ?

解決み!
違反を報告
引用返信 削除キー/



スレッド内ページ移動 / << 0 >>

このスレッドに書きこむ

Mode/  Pass/


- Child Tree -