يمر مجموعات متعددة من الحجج مجموعة في جافا سكريبت أسرع من وظيفة متعددة المكالمات ؟

StackOverflow https://stackoverflow.com/questions/1413230

سؤال

بعد أن أصبح غير مريح قليلا مع مكالمات متعددة في نفس الوظيفة ، مع معلمات مختلفة (كما هو موضح في دوم استعداد القسم من المدونة أدناه) ، قررت لاختبار تمرير معلمات لهذه المهمة من قبل بالتكرار عبر صفيف بدلا من ذلك (كما هو مبين في mouse_function_two).لدهشتي وجدت أن mouse_function_two ركض أسرع بكثير.

سؤالي هو ، mouse_function_two يعتبر جافا سكريبت أفضل الممارسات من mouse_function_one?

ملاحظة:أنا قلقة بعض الشيء قد لا يكون استخدام firebugs وحدة التحكم.الوقت الأداة بشكل صحيح!

المحاولة الأولى

function mouse_function_one (hover_selector, class_name, add_link) {

  hover_item = $(hover_selector)

  hover_item.each(function(){
    $(this).hover(
      function () {
        $(this).addClass(class_name);
        if ( add_link == true ) {
          $(this).click(function(){
            var href = $(this).find('a').attr('href');
            window.location.href = href;
          });

        }
        else return false;
      },
      function () {
        $(this).removeClass(class_name);
    });
  });
}

الثانية (أسرع) محاولة:

function mouse_function_two (args) {

  for (var i=0; i < args.length; i++) {

    hover_selector = $(args[i][0]);
    class_name = args[i][1];
    add_link = args[i][2];

    hover_item = $(hover_selector)

    hover_selector.each(function(){
      $(this).hover(
        function () {
          $(this).addClass(class_name);
          if ( add_link == true ) {
            $(this).click(function(){
              var href = $(this).find('a').attr('href');
              window.location.href = href;
            });

          }
          else return false;
        },
        function () {
          $(this).removeClass(class_name);
        });
    });

  }
}

رمز العميل:

// on dom ready
$(function(){

  console.time('f1');
  mouse_function_one('#newsletter .right', 'hovered', true);
  mouse_function_one('.block-couple div.right', 'hovered', false);
  mouse_function_one('.bulletin', 'selected', true);
  console.timeEnd('f1'); //speed is calculated as 104ms

  args = [];
  args[0] = ['#newsletter .right', 'hovered', true]; 
  args[1] = ['.block-couple div.right', 'hovered', false]; 
  args[2] = ['.bulletin', 'selected', true]; 

  console.time('f2');
  mouse_function_two(args);
  console.timeEnd('f2'); //speed is calculated as 10ms

});
هل كانت مفيدة؟

المحلول

إذا كان الثاني الروتينية بشكل أسرع ، ربما لأنه لا تفعل ما يفترض القيام به.إلقاء نظرة على هذا المقتطف:

  for (var i=0; i < args.length; i++) {

    hover_selector = $(args[i][0]);
    class_name = args[i][1];
    add_link = args[i][2];

    hover_item = $(hover_selector)

    hover_selector.each(function(){
      $(this).hover(
        function () {

مشكلتين هنا:

  1. كنت تستخدم الضمني المتغيرات العالمية.
  2. كتل في جافا سكريبت لا أعرض نطاق جديد.

أي من هذه سوف تسبب نفس علة ، إلى جانب أنها فقط يجعل مضاعف على يقين من أنه سوف تحدث:الإغلاق خلق hover() معالج الحدث وظائف تحتوي فقط على القيم النهائية حلقة التكرار.عند هذه معالجات وأخيرا دعا ، class_name سوف تكون دائما "selected", ، add_link سوف تكون دائما true.في المقابل ، الأصلي الخاص بك وظيفة سيطلق عليها مع مجموعة مختلفة من المعلمات في كل مرة ، والذي من شأنه أن يكون القبض في وظيفة نطاق من معالجات الأحداث ، وبالتالي تعمل كما هو متوقع.


أما عن أسلوب...الأمر فوضوي.لقد المغطى كامل وظائف الجسم في حلقة إزالة وصفي الحجج ، وإلى حد كبير في تعقيد استدعاء الدالة.

لحسن الحظ, يمكنك معالجة هذه المسألة أود أن أشير أعلاه ، تبسيط وظيفة ، و تبسيط الطريقة التي يطلق عليها جميعا دفعة واحدة:

// For starters, I've eliminated explicit parameters completely.
// args wasn't descriptive, and all JavaScript functions have an implicit
// arguments array already - so let's just use that.
function mouse_function_three () {

  // use jQuery's array iteration routine:
  // this takes a function as an argument, thereby introducing scope and
  // avoiding the problem identified previously
  $.each(arguments, function() {
    var class_name = this.class_name;
    var add_link = this.add_link;
    var selected = $(this.hover_selector);

    // no need to use selected.each() - jQuery event binding routines
    // always bind to all selected elements
    selected.hover(function() {
      $(this).addClass(class_name);
    },
    function() {
      $(this).removeClass(class_name);
    });

    // bring this out of the hover handler to avoid re-binding
    if ( add_link ) {
      $(selected).click(function(){
        var href = $(this).find('a').attr('href');
        window.location.href = href;
      });

    }
  }); // each set of arguments
}

كنت ثم استدعاء هذا الروتين الجديد مثل ذلك:

console.time('f3');
mouse_function_three( 
 {hover_selector: '#newsletter .right', class_name: 'hovered', add_link: true},
 {hover_selector: '.block-couple div.right', class_name: 'hovered', add_link: false},
 {hover_selector: '.bulletin', class_name: 'selected', add_link: true}
);
console.timeEnd('f3');

علما أن هذه التغييرات قد بشكل جيد للغاية في القضاء على أي فرق السرعة من المحاولة الأولى ، كما رمز فعال يفعل نفس الشيء ولكن مع خطوة إضافية من التعبئة ومن ثم استخراج المعلمات...

نصائح أخرى

هل هو قطعة عنق الزجاجة من التعليمات البرمجية؟ استخدام المصفوفات كما سائط يفتح لك ما يصل الى فئة كاملة من الأخطاء التي المعلمات المسماة حمايتك من. رمز 2ND يقرأ سيئة جدا، وإذا لم يكن بالفعل، نظرا الوقت، وسوف يثبت أن الحمار الكامل التصحيح. لذلك، ما لم يكن حاسما، ويبقيه عاقل. فقط عندما يكون إشكاليا حقا كود يجب أن تبدأ رمي ميزات اللغة معقولة الى نقطة الصفر خارج قليلا من السرعة.

وتحرير: كلما نظرت إلى رمز، ويبدو أن أقل متوازن المؤشر الخاص بك. وهناك عدد من الأشياء التي لم يؤخذ بها التي قد تؤدي إلى نتيجة مختلفة مثل تكلفة استدعاء الأسلوب المتكرر على الاحتجاج واحد وأن ملء صفائف الخ لا قياسها فيكم الحالة الثانية.

وكنت تنظر تمرير كائن JSON في قضيتك. الأطر مثل ExtJs ومسج تعتمد على هذه بشكل كبير كما يفعل مثل هذا يمنحك الكثير من المرونة (خاصة مع تطور API الخاص بك) ويتيح لك حزمة الكثير من البيانات في كائن واحد.

function mouse_function_three (args) { ... }

وسائط حيث تبدو ...

[{'hover_selector': ... , 'class_name': ... , 'add_link': ...}, {'hover_selector': ... , 'class_name': ... , 'add_link': ...}, ... ]

هل يمكن أن تمتد حتى ذلك عن طريق بما في ذلك القدرة على تحديد الخصائص الافتراضية لخاصية كل كائن على هذا النحو:

{
'default_hover_selector': 'asdf',
'default_class': 'asdf',
'add_link: false,
'items': [{'hover_selector': ... , 'class_name': ... , 'add_link': ...}, {'hover_selector': ... , 'class_name': ... , 'add_link': ...}, ... ]
}

وأعتقد أن هذا الحل يوفر لك أداء وintuitivity (هو أنه حتى كلمة) الذي تريده.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top