Вы пытаетесь проверить, равны ли два объекта? то есть: их свойства равны?
Если это так, вы, вероятно, заметили эту ситуацию:
var a = { foo : "bar" };
var b = { foo : "bar" };
alert (a == b ? "Equal" : "Not equal");
// "Not equal"
вам, возможно, придется сделать что-то вроде этого:
function objectEquals(obj1, obj2) {
for (var i in obj1) {
if (obj1.hasOwnProperty(i)) {
if (!obj2.hasOwnProperty(i)) return false;
if (obj1[i] != obj2[i]) return false;
}
}
for (var i in obj2) {
if (obj2.hasOwnProperty(i)) {
if (!obj1.hasOwnProperty(i)) return false;
if (obj1[i] != obj2[i]) return false;
}
}
return true;
}
Очевидно, что эта функция могла бы сделать с небольшим количеством оптимизации и способностью делать глубокую проверку (для обработки вложенных объектов: var a = { foo : { fu : "bar" } }
), но вы поняли идею.
Как указывалось для FOR, вам, возможно, придется адаптировать это для ваших собственных целей, например: разные классы могут иметь разные определения «равных». Если вы просто работаете с простыми объектами, вышеописанного может быть достаточно, в противном случае можно воспользоваться пользовательской функцией MyClass.equals()
.
Многопоточность делает много вещей, но я не думаю, что «упрощение» когда-либо является одним из них.
Нет.
Понятно, что многопоточность увеличивает сложность и является почти тривиальным способом добавления ошибок в код. Существуют проблемы параллелизма , такие как синхронизация , тупик , условия гонки и инверсия приоритета , чтобы назвать несколько
Во-вторых, повышение производительности не происходит автоматически. Недавно в журнале MSDN Magazine появилась отличная статья на эту тему. Существенные детали заключаются в том, что определенная операция занимала 46 секунд на десять итераций, закодированных как однопоточная операция. Автор наивно распараллелил операцию (один поток на четыре ядра), и операция упала до 30 секунд на десять итераций. Звучит великолепно, пока вы не примете во внимание, что теперь эта операция потребляет на 300% больше вычислительной мощности, но дает прирост эффективности только на 34%. Для такого выигрыша не стоит тратить всю доступную вычислительную мощность.
Прочтите закон Амдала , который лучше всего резюмируется следующим образом: «Ускорение программы, использующей несколько процессоров в параллельных вычислениях, ограничено временем, необходимым для последовательной части программы. . "
Оказывается, если только небольшая часть вашего приложения может работать параллельно, вы не получите большого выигрыша, но, возможно, получите много трудных для отладки ошибок.
Я собираюсь обеспечить некоторый баланс против единодушного «нет».
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Да, потоки сложны и могут вызвать целый ряд проблем. Все остальные указали на это.
Исходя из опыта, последовательность блокирующих операций чтения / записи в сокет (которая требует отдельного тега) намного проще , чем неблокирующие. С помощью блокирующих вызовов вы можете узнать состояние соединения, просто посмотрев на то, где вы находитесь в функции. При неблокирующих вызовах вам понадобится набор переменных для записи состояния соединения, а также их проверки и изменения каждый раз, когда вы взаимодействуете с соединением. При блокирующих вызовах вы можете просто сказать «прочтите следующие X байтов» или «читайте, пока не найдете X», и он действительно сделает это (или потерпит неудачу). С неблокирующими звонками, вам приходится иметь дело с фрагментированными данными, что обычно требует хранения временных буферов и их заполнения по мере необходимости. Вы также в конечном итоге проверяете, достаточно ли вы получили данных, каждый раз, когда получаете немного больше. Кроме того, вы должны вести список открытых соединений и обрабатывать неожиданные закрытия для всех из них.
Это не может быть намного проще, чем это:
void WorkerThreadMain(Connection connection) {
Request request = ReadRequest(connection);
if(!request) return;
Reply reply = ProcessRequest(request);
if(!connection.isOpen) return;
SendReply(reply, connection);
connection.close();
}
Я хотел бы отметить, что этот "прослушиватель" порождается из рабочего потока на соединение "- это то, как разрабатываются веб-серверы, и я предполагаю, что именно так спроектированы многие программные серверные приложения запросов / ответов.
Итак, в заключение, я испытал асинхронный спагетти-код сокетов, который вы упомянули, и порождал его рабочие потоки для каждого соединения оказались хорошим решением. Сказав все это, обсуждение проблемы обычно должно быть вашим последним средством.
Хотя я согласен со всеми здесь, говоря, что многопоточность не упрощает код, ее можно использовать для значительного упрощения взаимодействия с пользователем вашего приложения.
Рассмотрим приложение, в котором много интерактивных виджетов (в настоящее время я разрабатываю один, где это помогает) - в рабочем процессе моего приложения пользователь может «построить» текущий проект, над которым он работает. Для этого необходимо отключить интерактивные виджеты, которые мое приложение представляет пользователю, и представить диалоговое окно с неопределенным индикатором выполнения и дружественным сообщением «пожалуйста, подождите».
«Сборка» происходит в фоновом потоке; если бы это произошло в потоке пользовательского интерфейса, это сделало бы взаимодействие с пользователем менее приятным - в конце концов, это Нет ничего забавного в том, что нельзя сказать, можете ли вы щелкнуть виджет в приложении во время выполнения фоновой задачи (кашель, Visual Studio). Нельзя сказать, что VS не использует фоновые потоки, я просто говорю, что их пользовательский опыт можно улучшить. Но я отвлекся.
Единственное, что меня не устраивает в названии вашего сообщения, это то, что вы думаете об отключении потоков, когда вам нужно выполнить задачи - я обычно предпочитаю повторно использовать потоки - в .NET я обычно предпочитаю использовать пул системных потоков, создавая новый поток каждый раз, когда я хочу что-то сделать, ради производительности.
Я не хочу перевернуть, но что в этом файле конфигурации, который так долго загружается? В этом и заключается причина вашей проблемы, не так ли?
Возможно, перед тем, как создать другой поток для ее обработки, его можно разделить? Уменьшить, возможно, поместить в другой формат данных, который будет быстрее и т. Д.?
Как часто он меняется? Это что-то, что вы можете проанализировать один раз в начале дня и поместить переменные в общую память, чтобы последующие запуски вашей основной программы могли просто присоединиться и получить оттуда необходимые значения?
Я думаю, у вас нет другого выбора, кроме как иметь дело с потоками, особенно с сетевыми и параллельными соединениями. Делают ли потоки код проще? Я так не думаю. Но без них, как бы вы запрограммировали сервер, который может обрабатывать более 1 клиента одновременно?
Это отличный способ внести ошибки в код.
Правильное использование нескольких потоков непросто. Новые разработчики не должны пытаться это сделать.
На мой взгляд, многопоточное программирование довольно высоко по шкале сложности (и сложности), наряду с управлением памятью. Для меня отношение «Ммм, перебрось это в другую тему, все будет хорошо» слишком банально. Вы должны хорошо подумать, прежде чем разветвлять нити.
Это дает вам дополнительную работу по отладке условий гонки, а также по обработке блокировок и проблем с синхронизацией.
Я бы не стал использовать это, если в этом нет реальной необходимости.