Apakah ada cara yang lebih pendek yang lebih baik daripada melakukan iterasi pada array?
int[] arr = new int[] { 1, 2, 3 };
int sum = 0;
for (int i = 0; i < arr.Length; i++)
{
sum += arr[i];
}
klarifikasi:
Primer yang lebih baik berarti kode lebih bersih tetapi petunjuk tentang peningkatan kinerja juga diterima. (Seperti yang telah disebutkan: memisahkan array besar).
Ini tidak seperti saya mencari peningkatan kinerja yang mematikan - Saya hanya bertanya-tanya apakah jenis gula sintaksis ini belum tersedia: "Ada String.Join - apa sih int []?".
Jawaban:
Asalkan Anda dapat menggunakan .NET 3.5 (atau lebih baru) dan LINQ, coba
sumber
System.OverflowException
jika hasilnya lebih besar dari yang dapat Anda masukkan dalam bilangan bulat 32 bit bertanda (yaitu (2 ^ 31) -1 atau dalam bahasa Inggris ~ 2,1 miliar).int sum = arr.AsParallel().Sum();
versi yang lebih cepat yang menggunakan banyak inti CPU. Untuk menghindariSystem.OverflowException
Anda dapat menggunakanlong sum = arr.AsParallel().Sum(x => (long)x);
Untuk versi yang lebih cepat yang menghindari pengecualian overflow dan mendukung semua tipe data integer dan menggunakan instruksi SIMD / SSE data paralel, lihat paket nuget HPCsharpYa ada. Dengan .NET 3.5:
Jika Anda tidak menggunakan .NET 3.5 Anda dapat melakukan ini:
sumber
foreach
loop tersedia dalam semua versi C #.foreach
hanya menggantikan satu baris kode dengan yang lain dan tidak lebih pendek. Selain itu, aforeach
sangat bagus dan lebih mudah dibaca.foreach (int i in arr) sum += i;
Dengan LINQ:
sumber
Itu tergantung pada bagaimana Anda mendefinisikan dengan lebih baik. Jika Anda ingin kode terlihat lebih rapi, Anda dapat menggunakan .Sum () seperti yang disebutkan dalam jawaban lain. Jika Anda ingin operasi berjalan cepat dan Anda memiliki larik yang besar, Anda dapat membuatnya paralel dengan memecahnya menjadi sub-penjumlahan, lalu menjumlahkan hasilnya.
sumber
Alternatif juga untuk menggunakan
Aggregate()
metode ekstensi.sumber
Jika Anda tidak menyukai LINQ, lebih baik menggunakan foreach loop untuk menghindari keluarnya indeks.
sumber
Untuk larik yang sangat besar, mungkin ada gunanya melakukan kalkulasi menggunakan lebih dari satu prosesor / inti mesin.
sumber
Satu masalah dengan solusi loop for di atas adalah untuk array input berikut dengan semua nilai positif, hasil penjumlahannya negatif:
Jumlahnya adalah -2147483648, karena hasil positif terlalu besar untuk tipe data int dan meluap ke nilai negatif.
Untuk larik input yang sama, saran arr.Sum () menyebabkan pengecualian overflow dilemparkan.
Solusi yang lebih tepat adalah dengan menggunakan tipe data yang lebih besar, seperti "long" dalam kasus ini, untuk "sum" sebagai berikut:
Perbaikan yang sama berfungsi untuk penjumlahan tipe data integer lainnya, seperti short, dan sbyte. Untuk array tipe data integer unsigned seperti uint, ushort dan byte, menggunakan unsigned long (ulong) untuk jumlah tersebut menghindari pengecualian overflow.
Solusi for loop juga beberapa kali lebih cepat dari Linq .Sum ()
Untuk berjalan lebih cepat, paket nuget HPCsharp mengimplementasikan semua versi .Sum () serta versi SIMD / SSE dan paralel multi-core, untuk kinerja yang berkali-kali lebih cepat.
sumber
long sum = arr.Sum(x => (long)x);
yang bekerja dengan baik di C # menggunakan Linq. Ini memberikan akurasi penuh untuk penjumlahan untuk semua tipe data integer yang ditandatangani: sbyte, short, dan int. Ini juga menghindari pelepasan pengecualian luapan, dan kompak dengan baik. Performanya tidak setinggi for loop di atas, tetapi performa tidak diperlukan di semua kasus.Menggunakan foreach akan menjadi kode yang lebih pendek, tetapi mungkin melakukan langkah yang persis sama pada waktu proses setelah pengoptimalan JIT mengenali perbandingan dengan Panjang dalam ekspresi pengontrol loop-for.
sumber
Di salah satu aplikasi saya, saya menggunakan:
sumber
.Aggregate()
metode ekstensi.Peningkatan pada implementasi Parallel.ForEach multi-core yang bagus dari Theodor Zoulias:
yang berfungsi untuk tipe data integer unsigned, karena C # hanya mendukung Interlocked.Add () untuk int dan long. Implementasi di atas juga dapat dengan mudah dimodifikasi untuk mendukung tipe data integer dan floating-point lainnya untuk melakukan penjumlahan secara paralel menggunakan beberapa inti CPU. Ini digunakan dalam paket nuget HPCsharp.
sumber
Coba kode ini:
Hasilnya adalah:
sumber