Rust: خطأ في أداء ThreadRng

تم إنشاؤها على ٨ يوليو ٢٠١٧  ·  3تعليقات  ·  مصدر: rust-lang/rust

يعمل ThreadRng أبطأ بخمس مرات من ThreadLocalRandom في جافا.

أدير هذا المعيار في Rust:

#[bench]
fn bench_rnd(b: &mut Bencher) {
    b.iter(|| rand::thread_rng().gen_range::<f64>(2.0, 100.0));
}

النتيجة على الكمبيوتر المحمول الخاص بي هي:
اختبارات الاختبار :: bench_rnd ... البدلاء: 49 ns / iter (+/- 1)

ولكن إذا قمت بإجراء نفس المعيار على JHM:

<strong i="12">@Benchmark</strong>
public double testRnd() {
    return ThreadLocalRandom.current().nextDouble(2, 100);
}

النتيجة على جهاز الكمبيوتر المحمول هي:
وضع قياس الأداء Cnt يسجل وحدات الخطأ
Main.testRnd متوسط ​​20 9018 ± 0،094 نانو ثانية / مرجع سابق

لذا فإن الفرق هو 5.44 مرة يبدو وكأنه خطأ في الأداء.

ميتا

الصدأ:

rbose
rustc 1.20.0-nightly (c9bb93576 2017-06-24)
ثنائي: rustc
الالتزام-التجزئة: c9bb93576d4484edd1b3c40eb2aea0dfa0788851
تاريخ الالتزام: 2017-06-24
المضيف: x86_64-unknown-linux-gnu
الإصدار: 1.20.0-nightly
إصدار LLVM: 4.0

جافا:
برنامج OpenJDK 1.8.131

التعليق الأكثر فائدة

نظرًا لأن rand عبارة عن صندوق خارجي به مستودع خاص به ، فمن المحتمل أن تكون هذه المشكلة موجودة ، إلا إذا كنت قادرًا على إثبات أن هذا خطأ Rust ، وليس خطأ rand .

ومع ذلك ، فإن السؤال الذي يجب أن تطرحه حقًا ، ما هو نوع الأرقام العشوائية التي تحصل عليها؟ rand::ThreadRng عبارة عن RNG آمن من الناحية المشفرة ، لذلك سيكون في وضع غير مؤات في الأداء بالنسبة لمجموعات RNG التي لا يجب أن تكون آمنة. بالنظر إلى الوثائق ... "مثيلات ThreadLocalRandom ليست آمنة من الناحية المشفرة." مما يعني أنك لا تقوم حتى بإجراء مقارنة عادلة.

تشغيل معيارك كما هو مكتوب هو 21ns / iter بالنسبة لي.

يؤدي تعديل مقياس الأداء إلى التخزين المؤقت لنتيجة thread_rng() تسريعها

#[bench]
fn bench_rnd(b: &mut Bencher) {
    let mut rng = rand::thread_rng();
    b.iter(|| rng.gen_range::<f64>(2.0, 100.0));
}

إذا كنت أستخدم weak_rng() مع ذلك وتخلصت من أمان التشفير ، فإنه يتقدم إلى 3 ns / iter.

#[bench]
fn bench_rnd(b: &mut Bencher) {
    let mut rng = rand::weak_rng();
    b.iter(|| rng.gen_range::<f64>(2.0, 100.0));
}

ال 3 كومينتر

نظرًا لأن rand عبارة عن صندوق خارجي به مستودع خاص به ، فمن المحتمل أن تكون هذه المشكلة موجودة ، إلا إذا كنت قادرًا على إثبات أن هذا خطأ Rust ، وليس خطأ rand .

ومع ذلك ، فإن السؤال الذي يجب أن تطرحه حقًا ، ما هو نوع الأرقام العشوائية التي تحصل عليها؟ rand::ThreadRng عبارة عن RNG آمن من الناحية المشفرة ، لذلك سيكون في وضع غير مؤات في الأداء بالنسبة لمجموعات RNG التي لا يجب أن تكون آمنة. بالنظر إلى الوثائق ... "مثيلات ThreadLocalRandom ليست آمنة من الناحية المشفرة." مما يعني أنك لا تقوم حتى بإجراء مقارنة عادلة.

تشغيل معيارك كما هو مكتوب هو 21ns / iter بالنسبة لي.

يؤدي تعديل مقياس الأداء إلى التخزين المؤقت لنتيجة thread_rng() تسريعها

#[bench]
fn bench_rnd(b: &mut Bencher) {
    let mut rng = rand::thread_rng();
    b.iter(|| rng.gen_range::<f64>(2.0, 100.0));
}

إذا كنت أستخدم weak_rng() مع ذلك وتخلصت من أمان التشفير ، فإنه يتقدم إلى 3 ns / iter.

#[bench]
fn bench_rnd(b: &mut Bencher) {
    let mut rng = rand::weak_rng();
    b.iter(|| rng.gen_range::<f64>(2.0, 100.0));
}

لاحظ أيضًا أن Java ThreadLocalRandom عبارة عن PRNG متطابقة خطية بسيطة للغاية ، بينما Rust's rand thread_rng() يعتمد على ISAAC (يُدعى أن يكون) PRNG آمن مشفر والذي أغلى ثمناً ، لذا فإن هذا المعيار ليس مقارنة بالضبط بين التفاح والتفاح.

شكرا جزيلا على التفسير لك.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات