Neredeyse hiç değişmeyen “oldukça büyük” miktarda veri depolamanın pratik yolu?


14

Önceden hesaplanmış arama tabloları veya başka bir şey açısından düşünün. Uygulamamda sabit kodlama değerleri yerine bir veritabanı kullanmak hangi noktada daha mantıklı? Değerler değişmeyecek ve bakım geliştiricilerinden hoş bir şekilde ayrılmıştır. 100 değer, 1k, 10k, 100k? Yaklaşık 40 bin değer depolamak istiyorum. Şu anda makine tarafından üretilen bir switchdeyimdir (VS2010'un mutsuz olduğu).

Düzenle:

Merak eden biri varsa, şöyle yaklaştım: Verilerim 100k elementlik iki şamandıra dizisinde saklanabilirdi, ben de öyle yaptım. Veri oluşturmak için yaklaşık 20 saniye sürdü, bu yüzden bunu bir kez yaptım ve bir BinaryFormatter ile gömülü bir kaynağa serileştirdim. Verilerin paketinin açılması, uygulama başlangıcında yaklaşık 5 milisaniye sürer ve değiştirdiğim veritabanı uygulamasından (bu sabit kodlanmış değerler önceden depolanmıştı) neredeyse 45.000x daha iyi.

Yanıtlar:


5

Benim önerim, verileri bir dosya veya veritabanı tablosunda tutmaktır. Hız bir sorun değilse, dosyayı veya veritabanını (veritabanı daha iyidir) çalışma zamanında sorgulayın. Bellek bir sorun değilse, ancak biraz hız istiyorsanız, program başladığında verileri belleğe yükleyin. C # 'da bir karma tabloyu dizebilir, listeleyebilir veya (en iyi seçenek) kullanabilir ve çalışma zamanında ihtiyacınız olan verileri döndürmek için bir yönteme sahip olabilirsiniz (örneğin getDataValue (string keyToValue)).

Korumak çok zor olacağı ve büyük bir exe ayak izi ile sonuçlanacağı için switch deyimini kullanmamanızı tavsiye ederim.

Karma tablo örneğin http://support.microsoft.com/kb/309357


Sonuçta yaptığım bu: güncellenmiş yazımı kontrol et.
Bryan Boettcher

1
Veritabanı önerisi için +1. Veritabanları büyük veri hacimlerini depolamak için üretilmiştir ve bunları çok hızlı bir şekilde getirmenizi sağlar.
NoChance

Bunun için bir hashtable yerine sözlük kullanmanın daha iyi olduğu konusunda stackoverflow.com/questions/301371/… adresine bakın . YMMV
Chris McKee

6

Şahsen, belirli bir dağıtım veya düzeltme için düzenlemeye gerek kalmadan uygulamaya sabit kodlanmış herhangi bir miktarda veri depolamak için Tamamım.

Ancak, veri depolama ve veri erişim modelini sıkıca birleştirdiğinden ve yalnızca bir yöntem erişim yöntemi (switch parametresi ile) içerdiğinden, C # switch deyimini kullanarak verileri depolamak ve erişmek oldukça kötü bir uygulamadır.

Bir Hashtable veya Sözlük veri depolamak ve veri almak için ayrı sınıflar sağlamak ve bir kez arama Sözlükler nüfus tercih ediyorum.

Son zamanlarda, iş kurallarını ( SiteMap için akıcı arayüz veya vergi hesap görüşmesi soru kontrolü kurallar defenition için "calc" yöntemi) belirlemek için küçük DSL uygulamak ve daha sonra bu kuralları sorgulamak için ayrı bir nesne sağlamak için oldukça uygun buldum . Bu teknik, anahtar senaryo senaryosu için de geçerlidir.

Bu tür bir ayrışmanın en güzel avantajlarından biri, verilerinizi tanımlayan XXXk satır blobuna dokunmadan verilerinize bir dizi Görünüm uygulayabilmenizdir.


Cevabı bazı örneklerle uzattım.
Valera Kolupaev

2

Bir 40k hat anahtarı ifadesi biraz tartışmalıdır. Sorgu işlemlerini yine de yapmanız gerektiğini varsayıyorum, değil mi? Verileri kapsüllemeyi denediniz mi? Sonra performansı sınamak için koleksiyon üzerinde sorgu işlemleri gerçekleştirmek için LINQ kullanın. StopWatch gibi bir zamanlayıcı ile birim testleri yaparak somut zamanlar alın . Sonra, sadece işe yarayabileceğini düşünüyorsanız. Performansın kullanıcılar için kabul edilebilir olup olmadığına bakın.


2

İki kez böyle bir gereksinimim vardı. Uygulamalar, veritabanı kurulumu / erişimi gerekmeden bağımsız olarak tasarlanmıştır. Her iki durumda da verileri depolamak için XML dosyaları kullandım. Birincisi, 2.0 Framework üzerinde olan, veri aramak için eski stil XML ayrıştırma çağrıları kullandım. Daha yenisi için, 3.5 Framework üzerinde, ihtiyacım olanı bulmak için XML LINQ kullandım. Her iki durumda da, verilere erişim sınıflarda kapsüllenmiştir.


1

Burada önemli olan, ortak arayüzünüzün uygulamanızı kapsadığından emin olmaktır - ancak bu sizin sorunuz değildir ve yapmadığınızı düşünmek için bir neden yoktur. Bunun ötesinde, bu sadece kedere karşı bir performans meselesidir (ve performans farklılıkları önemsemeye değmeyebilir). Pratik bir çözüm olarak, VS 2010 sorunu için, vaka ifadesini her zaman vaka ifadeleri hiyerarşisine bölebilirsiniz - üst düzey, her biri 4000 vaka vaka ifadesine sahip diğer 10 yöntemden birini çağırabilir. Gerekirse 10'un her birini kendi dosyasına koyabilirsiniz. Biraz çirkin, ama yine de kod üretiyorsunuz.

Bir DB geçmek için numara gelince -Bir DB kullanılmadığında sorun olur.


Arayüzümün uygulamayı kapsadığı düşüncesini takdir ediyorum: kesinlikle öyle. İşlevsellik bir GetValuesForInput-type yöntemiyle gösterilir ve büyük deyim uygulamada gizlidir.
Bryan Boettcher

1

SQL Compact gibi bir şey kullanabilirsiniz. Verileri bir tabloya koyun ve DB dosyasını projede bırakın. Tablolar, bu miktarda veri için bir switch deyiminden daha uygundur.


1

Bence buradaki anahtar kelime 'zor'

Veriler asla değişmezse (örneğin, önceden hesaplanmış mathamatik değerler, renk sabitleri ve benzerleri), boyut sizin için yönetilebildiği sürece elbette kodu saklayın. Performans bir sorunsa, case / switch ifadelerinin diğer seçeneklere göre çok yavaş olacağını unutmayın.

Veriler neredeyse hiç değişmezse - örneğin, telefon alan kodları, ulusal sınırlar ve benzerleri - muhtemelen verileri bir şekilde harici olarak tutmaya çalışırım. Özellikle birkaç düzineden fazla değer almaya başladıysa.


1
Derleyicinin ne kadar iyi olduğuna bağlıdır. Delphi'de bir vaka bildirimi son derece verimli olabilir.
Loren Pechtel

1

Uygulamanıza büyük miktarda veri depolarsanız, programınız daha yavaş yüklenebilir ve bazılarının ikili dosyalar veya yürütülebilir dosyayla oynatılabilmesi durumunda kodu riske maruz bırakıyor olabilirsiniz.

Ayrıca, program birçok kez düzenlenmişse, kim bilir, yanlışlıkla bir sayının yanlış yazılması veya değişiklik komutunun bir sonucu olarak hataları ortaya çıkarabilirsiniz.

Gelecekte bazıları veri üzerinde sorgular çalıştırmayı isteyebilir, örneğin birisi bir sütunun ortalamasını isteyebilir, bu durumda uygulamanızı değiştirmeniz ve kullanıcılarınızın geldiği her sorguyu hesaplamak için bir yöntem eklemeniz gerekir ile kodunuzu üretime yükseltmek için tüm adımları uygulayın. Bu gerçekten iyi değil.

Verilerin ve kodun ayrılması, özellikle veriler büyükse iyi bir uygulamadır.

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.