Javascript verimliliği: "for" vs "forEach" [kapalı]


104

For () döngüleri ile .forEach arasındaki 2017'de Javascript'teki mevcut standart nedir.

Şu anda Udemy üzerinde Colt Steeles "Web Dev Eğitim Kampı" Yolumu çalışıyorum ve o iyilik forEachüzerinde foryaptığı öğretilerinde. Bununla birlikte, kurs çalışmasının bir parçası olarak alıştırmalar sırasında çeşitli şeyler aradım ve for-loop kullanmak yerine giderek daha fazla tavsiye buluyorum forEach. Çoğu insan for döngüsünün daha verimli olduğunu belirtiyor.

Bu, kursun yazıldığından beri (yaklaşık 2015) değişen bir şey mi yoksa her biri için gerçekten artıları ve eksileri mi?

Herhangi bir tavsiye çok takdir edilecektir.


11
Neden kendinizi birisinin 2017 standardı hakkındaki öznel fikrine bağlıyorsunuz? Temiz, sürdürülebilir kod yazmak, mühendislerin en sık kullanılan yapıları çok verimli hale getirmek için çok çalıştığını bilerek ve ardından belirli bir performans sorununuz olduğunda performansı optimize etmek gibi zamansız bir standart benimseyin

2
Yerli for, saf hız için yenmek zordur. forEach()her yineleme için bir geri arama çağırır; yani, bununla birlikte bir miktar ek yük taşıyor.
canon

1
Bir geliştirici olarak neredeyse hiç kullanmıyorum, işin çoğu harita, filtre veya azaltma yöntemleriyle yapılıyor.
AT

12
@AT, mapsadece yineleme için kullanan ve oluşturduğu yeni diziyi atan adamlardan biri olmadığınız sürece . Sadece bu sitedeki belirli işlev seçimini kaç kişinin düzeltmesi gerektiğini bilmiyorum.
canon

1
@canon kabul etti, döngü seçimi önemlidir ve kişi seçim yaparken bu tür yöntemlerin çıktılarını ve kalıntılarını akılda tutmalıdır. Okunabilirlik için düz "döngüler" den kaçınılması gerektiğine inanıyorum.
AT

Yanıtlar:


202

için

fordöngüler çok daha etkilidir. Bir koşul doğruyken yinelemek için özel olarak tasarlanmış , aynı zamanda bir adım mekanizması (genellikle yineleyiciyi artırmak için) sunan döngüsel bir yapıdır . Misal:

for (var i=0, n=arr.length; i < n; ++i ) {
   ...
}

Bu, -döngüler için her zaman daha verimli olacağı anlamına gelmez, sadece JS motorları ve tarayıcıları onları bu şekilde optimize etti. Yıllar geçtikçe, hangi döngü yapısının daha verimli olduğu konusunda tavizler olmuştur (için, while, azaltma, ters çevirme vb.) - farklı tarayıcılar ve JS motorları, aynı sonuçları üretmek için farklı metodolojiler sunan kendi uygulamalarına sahiptir. Tarayıcılar performans taleplerini karşılamak için daha fazla optimize ettikçe, teorik [].forEacholarak daha hızlı veya a ile karşılaştırılabilir bir şekilde uygulanabilir for.

Faydaları:

  • verimli
  • erken döngü sonlandırma (onur breakve continue)
  • koşul denetimi ( i<nherhangi bir şey olabilir ve bir dizinin boyutuna bağlı değildir)
  • değişken etki alanı ( var iyaprak iilmek uçlarının sonra kullanılabilir)

her biri için

.forEachöncelikli olarak diziler üzerinde yineleme yapan yöntemlerdir (ayrıca Mapve Setnesneleri gibi diğer numaralandırılabilirler üzerinde ). Daha yenidirler ve öznel olarak okunması daha kolay olan kod sağlarlar. Misal:

[].forEach((val, index)=>{
   ...
});

Faydaları:

  • değişken kurulumu içermez (dizinin her bir öğesi üzerinde yinelenir)
  • fonksiyonlar / ok fonksiyonları değişkeni bloğun kapsamına alır
    Yukarıdaki örnekte val, yeni oluşturulan fonksiyonun bir parametresi olacaktır. Böylece, valdöngüden önce çağrılan herhangi bir değişken , bittikten sonra değerlerini tutacaktır.
  • kodun ne yaptığını belirlemek daha kolay olabileceğinden öznel olarak daha sürdürülebilir - bir numaralandırılabilir üzerinde yineleniyor; bir for-döngü herhangi bir sayıda döngü şeması için kullanılabilirken

Verim

Performans, öngörülebilirlik veya yaklaşım söz konusu olduğunda genellikle biraz deneyim gerektiren karmaşık bir konudur. Ne kadar optimizasyon gerekebileceğini önceden (geliştirme sırasında) belirlemek için, bir programcının problem vakasıyla ilgili geçmiş deneyimleri ve olası çözümleri iyi bir şekilde anlaması gerekir.

Bazı durumlarda jQuery'nin kullanılması bazen çok yavaş olabilir (deneyimli bir geliştirici bunu biliyor olabilir), diğer zamanlarda sorun olmayabilir, bu durumda kütüphanenin tarayıcılar arası uyumluluğu ve diğer işlevleri gerçekleştirme kolaylığı (örn. AJAX, olay işleme), kazanılan geliştirme (ve bakım) süresine değer.

Diğer bir örnek, performans ve optimizasyon her şey olsaydı, makine veya montajdan başka kod olmazdı. Açıkçası, her biri kendi ödünleşimlerine sahip birçok farklı yüksek seviyeli ve düşük seviyeli dil olduğu için durum böyle değil. Bu ödünler arasında uzmanlaşma, geliştirme kolaylığı ve hızı, bakım kolaylığı ve hızı, optimize edilmiş kod, hatasız kod vb. Bulunur, ancak bunlarla sınırlı değildir.

Yaklaşmak

Bir şeyin optimize edilmiş kod gerektirip gerektirmeyeceğini tam olarak anlamıyorsanız, genellikle önce bakımı yapılabilir bir kod yazmak iyi bir kuraldır. Oradan, gerektiğinde daha fazla dikkat edilmesi gereken şeyleri test edebilir ve tam olarak belirleyebilirsiniz.

Bununla birlikte, belirli bariz optimizasyonlar genel uygulamanın bir parçası olmalı ve herhangi bir düşünce gerektirmemelidir. Örneğin, aşağıdaki döngüyü düşünün:

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

Döngünün her yinelemesi için JavaScript, arr.lengthher döngüde bir anahtar arama maliyetlendirme işlemlerini alıyor. Bunun olmaması için hiçbir sebep yok:

for (var i=0, n=arr.length; i < n; ++i){}

Bu aynı şeyi yapar, ancak yalnızca bir arr.lengthkez alır , değişkeni önbelleğe alır ve kodunuzu optimize eder.


25
Zaman, uygulama veya mikro kıyaslama testinde tek bir noktaya bağlı olmayan mükemmel, kapsamlı, varsayımsal olmayan cevap.

1
Mükemmel, tam da aradığım buydu ve videodan çok daha fazla derinlik veriyor. Bunu gerçekten takdir ediyorum, yeni olmak öğrenilecek çok şey var ve bunlar, gelecekte sizi engelleyebilecek sebepsiz yere birini diğerine tercih ederek atlaması kolay şeyler. Çok teşekkürler!
tonyrobbins

2
for-döngü genellikle hata ayıklama açısından bir avantaja sahiptir: içine adım atmak, kesme noktası koymak ve denetlemek önemsizdir. ForEach () ile ekstra geri arama seviyesi işleri biraz karmaşıklaştırabilir.
Eric Grange

1
@FelipeBuccioni teşekkür ederim, aslında motorların uzunluğun önbelleğe alınıp alınmadığını belirlemek için bir dizinin mutasyona uğratılıp dönüştürülmeyeceğini kontrol ettiğini düşünüyorum. Yine de, eski amaçlar için optimizasyon motorlarının o kadar cömert olmadığını ve uzunluğun her yinelemede bir performans artışı olduğunu düşünüyorum. Makalenize bir göz atacağım ve zamanım olduğunda bunu cevaba dahil edeceğim ya da umarım topluluğun seçkin bir üyesi benim için bir düzenleme olarak bir değişiklik yapacaktır :)
vol7ron

6
Bu cevap ve ifadedeki açıklamadan gerçekten zevk alıyorum [...], if performance and optimization was everything, there would be no other code than machine or assembly.. letBir blok kapsamı yerel değişkeni bildirme ifadesi ile, ikinci faydasının, desteği olmayan bir ortamda olmadığı sürece döngü forEachüzerinde artık bir avantaj olmadığına inanıyorum . forlet
user7393973
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.