[過去ログ] ふらっと C#,C♯,C#(初心者用) Part155 (1002レス)
前次1-
抽出解除 レス栞

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
リロード規制です。10分ほどで解除するので、他のブラウザへ避難してください。
51
(8): 41 (ワッチョイ 8341-643o) [] 2022/06/22(水) 22:57:40.86 ID:LVeGoA3E0(1) AAS
みなさんありがとうございます。書いたコードはこんな感じです。
.NET Framework4.8 の Form アプリで、画面にlabelを1つ置いています。
私の環境だとDebug, Releaseビルドに関わらず100倍くらいBが早いです。

public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private Random _random = new Random();
private void Test(Func<int> func) {
var sw = Stopwatch.StartNew();
var count = 10000;
for (var i = 0; i < count ; i++) {
label1.Text = func().ToString();
Application.DoEvents();
}
sw.Stop();
Console.WriteLine($"{sw.ElapsedMilliseconds} msec");
}
private int MethodA() {
return _random.Next(1, 100);
}
private int MethodB() {
var random = new Random();
return random.Next(1, 100);
}
private void button1_Click(object sender, EventArgs e) {
Test(MethodA);
Test(MethodB);
}
}
53
(2): デフォルトの名無しさん (ワッチョイ 2324-zXsU) [sage] 2022/06/22(水) 23:17:07.34 ID:MLZMXa4p0(2/3) AAS
>>51
Test(MethodB);
Test(MethodA);
こうやって逆にして見ると今度はAの方が100倍速くなるかもね
Stopwatchクラスはこんな風に糸も簡単に結果が変わるからパフォーマンス測定にはあんまり向かない

あとRandomと比べてlabe1.Text = がかなりのボトルネックになってる可能性あるから、そうだとしたらRandomのパフォーマンス差なんて誤差の範囲内ってことになってしまう
よって強いてTest()でやるとしたら自分ならこうやって最後だけアウトプットするようにする
int num = 0;
for (int i = 0; i < 10000; i++) num += func();
label1.Text = num.ToString();
55
(1): デフォルトの名無しさん (ワッチョイ 5a01-UZ+b) [sage] 2022/06/22(水) 23:50:09.49 ID:XpS14TAH0(3/3) AAS
>>51
Application.DoEvents()はずしても100倍の差が出る結果は同じなの?
78
(1): 64 (ワッチョイ 5f49-sER5) [sage] 2022/06/23(木) 15:56:54.89 ID:uYSGjbtO0(7/7) AAS
>>76
76(1): デフォルトの名無しさん (ブーイモ MM67-oPsP) [sage] 2022/06/23(木) 15:31:00.54 ID:te570uEsM(1/3) AAS
>>73
このintの和のケースではBは最適化が効いて return 5; になっていると思われる
Randomでは同様の最適化はできないはずだから状況が違う
ちなみにintのほう、5+i にしてても"ほぼ"一緒やったよ。差異も似たようなもん

言いたいのは、>>51(=41)が言う「AとBにこんなに差が出るがなぜか」について、
4.8のコンソールアプリでは51が言うほどの有意な差は出なかったということ。

ちなみにワイの環境でMeanの差異は50ms程度でBが早いってなったけど、
まあこれは51が言ってるほどじゃないけど環境依存もあるからなんとも
(Randomのほうもコメントで切替えつつ検証した、差異も同じ)

原因についてのワイの推測は間違ってたってことはこれで自分で明らかにしちゃったけど、
Randomの1ms~も多分違うんじゃないかなとはこれで思う
79: デフォルトの名無しさん (ブーイモ MM67-oPsP) [sage] 2022/06/23(木) 16:15:51.40 ID:te570uEsM(3/3) AAS
>>78
切り分けの仕方が不適切なんだよ
>>51のコードではボトルネックは明らかにTextやToStringやRandomの実装にあり、フィールドアクセスの有無やプロパティ自体のオーバーヘッドなんか誤差
>>73
73(2): 64 (ワッチョイ 5f49-sER5) [sage] 2022/06/23(木) 14:15:31.83 ID:uYSGjbtO0(5/7) AAS
ちなコードの一部
private void Test(Func<int> func)
{
for (var i = 0; i < 10000; i++)
{
Console.CursorLeft = 0;
Console.Write($"{i}{func()} random");
}
}

//private int MethodA()
//{
// v = 5 + 5;
// return v;
//}

//private int MethodB()
//{
// int v = 5 + 5;
// return v;
//}

private int MethodA() => _random.Next(1, 100);

private int MethodB() => (new Random()).Next(1, 100);

[Benchmark]
public void executeA() => Test(MethodA);

[Benchmark]
public void executeB() => Test(MethodB);
のような超マイクロベンチマークとは測ってるものが全然違うわけ
その処理時間の大小が定性的に同じだったとしても、それは恐らく偶然
定量的に評価しないと意味がない
82
(1): デフォルトの名無しさん (ワッチョイ a75f-cRYK) [sage] 2022/06/23(木) 18:02:24.84 ID:a115LlJm0(1) AAS
>>51
>>58
58(5): デフォルトの名無しさん (スッププ Sdba-oPsP) [sage] 2022/06/23(木) 00:47:12.21 ID:VlRKcYRwd(2/3) AAS
あと、Bの方は頻繁に同じ値が返ってないか?
Randomの引数なしコンストラクタは現在のミリ秒単位の時刻をシードに設定するから、1ms以内に生成されたRandomオブジェクトは全て同じ結果を返すはず
前述の通りTextプロパティの変更は非常に重いので、値が変わらない場合は実際の変更を省略する実装になっている可能性がある
の情報を信じて書いたけど
これで大体同じような数字が出たら>>58の通りベンチの取り方の問題のせいで出た差だと思うよ
MethodA,MethodB自体は>>72
72(2): 64 (ワッチョイ 5f49-sER5) [sage] 2022/06/23(木) 14:13:54.26 ID:uYSGjbtO0(4/7) AAS
コンソールアプリ、BenchmarkDotNetでやってみたら大して変わらんかったわ
Randomじゃなくてintの和でも同じ傾向
速度の違いはデバッグ時の状況の影響かもね

ちなControl.Textがうんたらの人たちは、ただの改善おじさんやな
比較の話で共通部分のコード直せって意味わからんわな
も検証してくれた通り変わらないはず
というか今MethodBのほうをどこかで使ってるんだとしたら、性能なんかより1ms以内連続して同じ値が出るような乱数でも問題無い使い方なのかを気にするべき

public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private int _random = 0;
private void Test(Func<int> func) {
var sw = Stopwatch.StartNew();
var count = 10000;
for (var i = 0; i < count ; i++) {
label1.Text = func().ToString();
Application.DoEvents();
}
sw.Stop();
Console.WriteLine($"{sw.ElapsedMilliseconds} msec");
}
private int MethodA() {
return _random++;
}
private int MethodB() {
return (int)DateTimeOffset.Now.FromUnixTimeMilliseconds;
}
private void button1_Click(object sender, EventArgs e) {
Test(MethodA);
Test(MethodB);
}
}
91
(2): デフォルトの名無しさん (ワッチョイ ca2d-MKW/) [sage] 2022/06/23(木) 20:56:11.83 ID:pqpGOzkV0(2/6) AAS
>>51
皆が指摘してるように余計な処理を省いたら、たぶん、結果が逆転すると思う
(自分の所では逆転してMethodAの方が60倍位速かった)

private void Test2( Func<int> func )
{
var sw = Stopwatch.StartNew();
var count = 10000; // ※速すぎて結果が0msecになると思うから1桁増やした方が良い
for ( var i = 0; i < count; i++ )
{
func();
}
sw.Stop();
Console.WriteLine( $"{sw.ElapsedMilliseconds} msec" );
}

private async void button2_Click( object sender, EventArgs e )
{
await Task.Run( () => Test2( MethodA ) );
await Task.Run( () => Test2( MethodB ) );
}
92: デフォルトの名無しさん (ワッチョイ a702-KtZt) [sage] 2022/06/23(木) 20:58:51.74 ID:ey2ezatM0(3/4) AAS
少なくとも >>51 のコードでは、Label.Text の更新とApplication.DoEventの時間測ってるのと変わらん
93: デフォルトの名無しさん (ワッチョイ ca2d-MKW/) [sage] 2022/06/23(木) 20:59:14.76 ID:pqpGOzkV0(3/6) AAS
>>91ほど変えなくても
>>51
label1.Text = func().ToString();

func();
に置き換えるだけで結果が逆転するな
前次1-
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.043s