2014-01-07 2 views
-2

Ниже мой маленький рефакторинг (+ некоторый дополнительный код из-за out-parameters) простейший метод, где я попытался ускорить работу с Parallel.Invoke (...).C# Parallel.Invoke (улучшения с нулевой скоростью)

(пожалуйста, игнорируйте async слово внутри переменных :)).

Синхронная версия - то же самое - с синхронными вызовами для тех же 7 методов.

Все 7 методов довольно просты - они просто заполняют и возвращают коллекцию.

Теперь - то, что я нахожу удивительным образом: оба методы выполняет практически идентичного времени (~ 6 секунд).

Как это возможно или Я что-то упустил?

private static void GenerateCachingHelpersAsync(
    SingleVODCache _svc, 
    Dictionary<int, DataRow> _dicFirstContentsFilter, 
    DataSet _ds, 
    out ConcurrentDictionary<string, DataRow> _cdicValidContentCatalogPrices, 
    out ConcurrentDictionary<int, DataRow> _cdicAllMetaDataHelper, 
    out List<KeyValuePair<int, int>> _helperContentMetaDataSync, 
    out ConcurrentDictionary<int, DataRow> _cdicAllAssetsHelper, 
    out List<KeyValuePair<int, int>> _helperContentAssetsSync, 
    out Dictionary<int, OneContentAllViewsHelper> _dicAllContentsViewsHelper, 
    out ConcurrentDictionary<int, List<Category>> _cdicValidContentCategories 
    ) 
    { 
    ConcurrentDictionary<string, DataRow> _cdicValidContentCatalogPricesAsync = new ConcurrentDictionary<string, DataRow>(); 
    ConcurrentDictionary<int, DataRow> _cdicAllMetaDataHelperAsync = new ConcurrentDictionary<int, DataRow>(); 
    List<KeyValuePair<int, int>> _helperContentMetaDataSyncAsync = new List<KeyValuePair<int, int>>(); 
    ConcurrentDictionary<int, DataRow> _cdicAllAssetsHelperAsync = new ConcurrentDictionary<int, DataRow>(); 
    List<KeyValuePair<int, int>> _helperContentAssetsSyncAsync = new List<KeyValuePair<int, int>>(); 
    Dictionary<int, OneContentAllViewsHelper> _dicAllContentsViewsHelperAsync = new Dictionary<int, OneContentAllViewsHelper>(); 
    ConcurrentDictionary<int, List<Category>> _cdicValidContentCategoriesAsync = new ConcurrentDictionary<int, List<Category>>(); 

    Parallel.Invoke(
     () => 
     { 
      _cdicValidContentCatalogPricesAsync = BuildValidContentCatalogPricesHelper(_ds.Tables[GetCMSDataTableIndex(m_eCMSDataTablesIndexes.CONTENT_CATALOG_PRICE_SYNC)]); 
     }, 
     () => 
     { 
      _cdicAllMetaDataHelperAsync = BuildAllMetaDataHelper(_ds.Tables[GetCMSDataTableIndex(m_eCMSDataTablesIndexes.META_DATA)]); 
     }, 
     () => 
     { 
      _helperContentMetaDataSyncAsync = BuildContentMetaDataSyncHelper(_ds.Tables[GetCMSDataTableIndex(m_eCMSDataTablesIndexes.CONTENT_META_DATA_SYNC)]); 
     }, 
     () => 
     { 
      _cdicAllAssetsHelperAsync = BuildAllAssetsHelper(_ds.Tables[GetCMSDataTableIndex(m_eCMSDataTablesIndexes.ASSETS)]); 
     }, 
     () => 
     { 
      _helperContentAssetsSyncAsync = BuildContentAssetsSyncHelper(_ds.Tables[GetCMSDataTableIndex(m_eCMSDataTablesIndexes.CONTENT_ASSET_SYNC)]); 
     }, 
     () => 
     { 
      _dicAllContentsViewsHelperAsync = BuildAllContensViewsVotesHelper(_ds.Tables[GetCMSDataTableIndex(m_eCMSDataTablesIndexes.CONTENT_VIEWS)], _dicFirstContentsFilter, _svc.MetaData.HowManyPastDaysForMostViewed); 
     }, 
     () => 
     { 
      _cdicValidContentCategoriesAsync = BuildValidContentCategoriesHelper(_ds.Tables[GetCMSDataTableIndex(m_eCMSDataTablesIndexes.CONTENT_CATEGORY_SYNC)], _dicFirstContentsFilter, _svc.AllCategories); 
     } 
     ); 

    _cdicValidContentCatalogPrices = _cdicValidContentCatalogPricesAsync; 
    _cdicAllMetaDataHelper = _cdicAllMetaDataHelperAsync; 
    _helperContentMetaDataSync = _helperContentMetaDataSyncAsync; 
    _cdicAllAssetsHelper = _cdicAllAssetsHelperAsync; 
    _helperContentAssetsSync = _helperContentAssetsSyncAsync; 
    _dicAllContentsViewsHelper = _dicAllContentsViewsHelperAsync; 
    _cdicValidContentCategories = _cdicValidContentCategoriesAsync; 
    } 
+3

Ваши расчеты связаны с ЦП. Привязана к вводу/выводу или связана с памятью? – matcheek

+0

CPU/Memory bound. Нет операций ввода-вывода. – sabiland

ответ

2

Parallel.Invoke метод будет possibly run the code asynchronously в зависимости от того, будет ли код работать быстрее синхронно или нет. В вашем случае, если вы просто заполняете коллекции и нет дорогостоящих вызовов ввода-вывода или услуг, возможно, это просто синхронизирует все.

Что нужно сделать, это группировать недорогое строительство в один блок кода, а затем разделять более дорогие вызовы (например, DB или веб-сервис) на отдельные блоки, так как они, скорее всего, добавят больше времени ожидания.

EDIT: Дополнительная цитата из MSDN

Нет гарантии сделаны о том порядке, в котором операции выполнения или выполнить ли они параллельно.

Смежные вопросы