Програма Excel VBA працює лише на швидкості 25%


5

У мене програма VBA працює на моєму чотирьохядерному процесорі Acer Aspire S3 Ultrabook. Проблема полягає в тому, що вона використовує лише 25% CPU (інші комбіновані процеси використовують ~ 1%). Ноутбук працює під керуванням Windows 8.0. Видання Excel 2013 (32-біт). Використовується лише 55% системної оперативної пам'яті, Excel - половина з 55%.

Я думаю, що тільки 25% використовується, тому що тільки один ядро ​​використовується Excel. Однак я не маю нічого, щоб підтримати цю теорію. Як прискорити програму?

Дякую.



4
Звуки, як Excel / VBA не може бути кращою платформою для вашої програми.
Ƭᴇcʜιᴇ007

2
Якщо ви турбуєтеся про час виконання, перенесення вашої обчислювальної логіки в іншу платформу буде дуже гарною ідеєю. Я досягнув ~ 1000x прискорення портування деякого дуже обчислювально інтенсивного коду (Excel 03) VBA до C #: ~ 4 години проти ~ 15 секунд. Аналогічний алгоритм в обох випадках; VBA вже отримала 5-10-кратне прискорення над наївною реалізацією, кешуючи значеннями змінних, замість того, щоб кожен раз читати клітинку і вимикати оновлення електронної таблиці на екрані кожного разу, коли клітина змінювалася під час обчислення.
Dan Neely

5
Легко зробити повільну роботу VBA, але є багато трюків, щоб зробити її набагато швидше, навіть в одному ядрі. Ви можете отримати 4-кратне прискорення, якщо ви можете використовувати всі ядра - але це можливо, що 100x прискорення чекає, що відбудеться, змінивши кілька рядків коду. Можливо, ви можете показати, де ви думаєте, що програма витрачає час - ми могли б допомогти вам прискорити її. Приклад: оголосити найбільш часто використовувані змінні як Double або Long (замість вибору VBA Variant відсутність декларації). Це може мати велике значення ...
Floris

1
Що таке і де це говорить вам, що ви використовуєте тільки 25% це звучить як помилка програмування з участю запису даних

Відповіді:


6

Мені здається, що програма, яку ви намагаєтеся використовувати, є однопотоковою, тобто вона може використовувати лише одне ядро, вона не знає, що інші існують. Там дійсно не є конкретним способом прискорити це за винятком, щоб купити процесор з більш швидкою одноядерної тактовою частотою або використовувати програму, яка підтримує багатопоточність.


Дякуємо за відповідь. Якби я отримав 64-бітне видання Excel, чи буде він працювати на всіх ядрах? Знову дякую.
tropical

4
@tropical No. Перемикання на 64 біт дозволить процесу використовувати більше 4 Гб пам'яті, однак це не дозволить їй працювати на більшій кількості ядер.
Keltari

11

Все, що наведено нижче, стосується Excel 2007 і раніше. Відповідно до посилання @ ʜcʜιᴇ007 опубліковано в коментарях вище, є деяка рідна підтримка багатопоточності в Excel 2013. Тим не менш, попередження просто забути, якщо ви досвідчений програміст все ще застосовується.

На жаль, VBA не підтримує багатопоточність, тому розрахунки VBA будуть обмежені одним ядром вашого процесора.

Тим не менш, існує розширений спосіб обманювати VBA у виконанні декількох потоків, генеруючи файли VBscript і виконуючи їх одночасно. Це обходить проблему, запустивши код за межами процесу Excel і дозволяє Windows керувати ресурсами, виділеними для різних потоків.

Тим не менш, переведення цього на роботу буде ймовірно означати повне переосмислення логіки вашого коду (тобто вам доведеться з'ясувати, як розділити завдання таким чином, що має сенс для їх одночасного запуску), що може Дуже добре бути неможливим для вашого проекту. Я ніколи цього не реалізовував, тому не можу допомогти вам у цьому більше, ніж розповісти вам те, що я вже казав вам.

Якщо ви хочете вступити в кролячу дірку, хоча, ось цікавий блог що показує приклад цього. Будьте обережні: якщо ви не виконаний програміст, ви можете забути цю ідею і просто прийняти, що VBA працює в одному потоці.

Інші ресурси щодо переповнення стека для сміливих:
https://stackoverflow.com/q/19159025/657668
https://stackoverflow.com/q/5721564/657668

Є, звичайно, інші способи оптимізації коду VBA без використання декількох потоків. Не бачачи вашого коду, неможливо зробити чіткі пропозиції, але тут є кілька звичних підозрюваних:

  • Завантажуйте дані з аркуша в масив для більш швидкої обробки. Взаємодія з робочим листом є головним вузьким місцем у виконанні VBA, і їх можна звести до мінімуму, працюючи з масивами.
  • Це пов'язано з тим, що Excel перераховує книгу після кожної зміни клітинки. Цього можна уникнути, встановивши Application.Calculation = xlManual. Просто переконайтеся, що ви повернетеся назад Application.Calculation = xlAutomatic перед виходом з підпрограми.

Крім того, я вважаю, що він працює на потоці інтерфейсу користувача, тому він блокує інтерфейс під час обробки (що стає помітним, якщо ви спробуєте використовувати UDF для спеціального форматування).
Casey

Чому ви хочете завдати шкоди цьому безумству, коли ви могли б написати свою програму краще мовою (як VB.NET, так і C #, можливо, краще, ніж VBA), що само собою працює швидше (JIT-компіляція проти інтерпретації), фактично підтримує паралелізм і все ще може взаємодіяти з Excel через Office PIAs?
Matteo Italia

2

Як і інші, VBA не є багатопоточним. Якщо ви хочете прискорити роботу, ви можете розглянути можливість написання користувацьких функцій (UDF) іншою мовою.

Я б рекомендував вам ExcelDNA і використовуючи C # або VB.Net. Вони дуже прості у використанні, якщо ви вже знаєте, як написати деякі C # і ви можете керувати багатопоточністю в межах UDF.

http://exceldna.codeplex.com/


1
У більшості випадків, коли ви бажаєте зробити це, ви повинні дійсно Подумайте, чи є Excel правильним інструментом для роботи. Молотки й цвяхи ...
sapi

Крім того, я згоден з вами, в галузі фінансів є багато випадків, коли Excel не є найкращим рішенням, але гідним рішенням, іноді трейдерам доводиться проводити симуляції Монте-Карло або моделювання ризиків. Ці переваги значною мірою від багатопоточності. Ви можете створити належну інфраструктуру, але більшість менших організацій будують додатки Excel, оскільки вони не мають ресурсів для створення складної інфраструктури.
BlueTrin

2

Відмова від відповідальності: це не правильна відповідь, але я знаходжу багато користувачів, яким потрібно знайти цей тип задніх разом з іншими відповідями щодо використання лише одного ядра, і моя репутація занадто низька, щоб розмістити його як коментар.

Схоже, ваш сценарій VBA використовує тільки одне ядро, і це може бути добре!

Оскільки інші вже згадували у вже хороших відповідях, я думаю, важливо знати інші аспекти цього питання, щоб допомогти вам знайти відповідне рішення. Як же ви прискорити програму?

  • 100% використання процесора в огляді системи не означає, що ваша програма йде так швидко, як може : може бути багато непотрібних речей, намагайтеся шукати "Оптимізація VBA для швидкості". Будь-яка хороша пошукова система дасть вам корисні відповіді з мережі Stack Exchange. Перейти на час, витрачений на обчислення, а не на використання процесора.
  • VBA в Excel не обов'язково є найкращим інструментом для виконання роботи : для довготривалих обчислень під час перебору цифр може бути корисно експортувати дані з Excel і використовувати іншу платформу, залежно від ваших навичок програмування. Є дуже багато на вибір, деякі інтегруються з платформою Microsoft і мають значно краще досяжний продуктивність ( робити непотрібні речі застосовується і тут).
  • Запуск 100% -ного процесора, ймовірно, не дасть вам 4-кратного збільшення швидкості над запущеним лише 25% : залежно від того, наскільки добре ви розбиваєте свій розрахунок, ви можете досягти лише 2 разів на 4 ядрах. Але є випадки, які йдуть так само добре майже 4-кратний приріст на 4-х ядрах - наприклад, якщо розрахунок на кожному рядку повністю не залежить від будь-яких інших даних у вашій таблиці. Подивитися Закон Амдала у Вікіпедії.
  • Можливо, не варто намагатися використовувати більше ядер : хоча це може бути корисним у деяких випадках, зробити обчислення більш ніж одним ядром може бути (і зазвичай є) на порядок складніше завдання, що вимагає деякої ретельної експертизи в техніці програмування (див. це питання для загального огляду).
  • Бонус: Можливо, вам взагалі не потрібно прискорювати програму. Якщо розрахунок займає, скажімо, три хвилини, і ви запускаєте його тільки раз на день, то чому б не встати трохи зі свого крісла і розтягнути свої жорсткі кістки? Ви ризикуєте витрачати дні на налаштування вашої програми, щоб мати змогу запустити її через два хвилини тридцять, що розраховується лише в дуже довгостроковій перспективі. Хороший програміст витрачає свій час на оптимізацію, коли його дійсно варто, так що нехай вас надихне хороші програмісти :)

0

Як і інші вище сказали, різьба буде відповідь, але це не є реальним рішенням, і оновлення до 64 біт зробить незначну різницю. Одна річ, яку ви можете спробувати зробити, це підвищення пріоритету процесу, ви можете побачити, як це зробити тут .

Важко сказати, чи буде це зробити ваш скрипт швидшим, тому що в іншому місці програми може бути ще одне вузьке місце (наприклад, читання / запис з диска), але воно принаймні дозволить Windows знати, що це більш високий пріоритет, ніж ваш інші процеси.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.