Ders 12 / 26
Maliyet İzleme
Dört yüz isteklik kurgu bir iş yükünde istek başına belirtecin defterinin tutulması ve dağılımın kuyruğunun sayılması: ortalama 81,6 belirteç iken ortanca 69, yüzde 99 dilimi 224 ve en büyük istek 303. En pahalı yüzde bir toplam belirtecin 0,0299'unu, en pahalı yüzde on ise 0,2124'ünü harcıyor. İki koşumda ortalama 81,6'dan 83,0'a çıkarken en pahalı yüzde birin payı 0,0299'dan 0,0409'a gidiyor, yani kararlı olan ortalama, oynayan kuyruktur. Faturanın kalemleri ayrıldığında yönerge 0,3921, konuşma durumu 0,3658 ve yeni bilgi taşıyan talep metni yalnız 0,1190 tutuyor. Konuşma durumunu kısaltan üç politika istek başına belirteci 81,6'dan 50,5'e indiriyor ama doğru etiket başına okunduğunda sıralama değişiyor.
İçindekiler
Önceki üç ders çağrının ağ tarafını ölçtü: hız sınırına takılan istek yeniden denendi, yinelenen bağlam önbelleğe alındı, bağlam boyutu ve kurulum değiştirilerek gecikme sınıfı düşürüldü. Üçü de bir şeyi ucuzlattı ve hiçbirinde ne kadara ucuzladığı sorulmadı. Gecikme sınıfı kullanıcının ölçüsüdür; faturanın birimi değildir.
Bu dersin birimi belirteçtir. Para birimi yazılmaz, çünkü fiyat sağlayıcıya ve zamana bağlıdır; belirteç sayısı ise düzeneğin kendi ürettiği bir sayıdır ve koşumdan koşuma taşınır. Ölçülecek iki şey vardır: bir isteğin kaç belirtece mal olduğu ve bu sayının istekler arasında nasıl dağıldığı. İkincisi olmadan birincisi yanıltır.
- UK31. Kod bir benzeticidir; gerçek bir uç nokta çağrılmaz. Talepler, konuşmalar ve belgeler kurgudur, tohum 20260218.
- UK32. Maliyet muhasebesinin yordamı tekrarlanmaz. Ölçüt toplama, gösterge tablosu ve birim maliyet dağıtımı M16’nın gözlemlenebilirlik kursunda, M22’de ve M23’ün bulut yönetişimi ve maliyet kursunda ölçüldü. Buraya eklenen tek şey birimdir: bir isteğin bedeli belirteçle yazılır.
- UK33. İş yükü bu derste tekil talep değil konuşmadır. Durum istemcide taşınır ve her istekte yeniden gönderilir; bir konuşmanın üçüncü isteği birinci isteğin metnini de içerir. Bu, kuyruğun kaynağıdır.
- UK34. Konuşma uzunlukları
[1, 2, 3, 5, 8, 12]kümesinden ağırlıklı seçilir. En uzun konuşmanın en son isteği bile bağlam penceresinin altında kalır, bu yüzden bu derste kırpma kararı devreye girmez; kırpmanın bedeli M28/K01’de ölçüldü. - UK35. Bir istek bir ya da birkaç çağrıdan oluşur. Yeniden deneme yordamı tekrarlanmaz; deftere yalnız kaç çağrı yapıldığı ve her çağrının giriş ile çıkış belirteci yazılır.
- UK36. Yeniden denemede benzeticinin tohumu bir artırılır. Aynı istem aynı tohumla aynı yanıtı verdiği için ikinci deneme ancak böyle başka bir sonuç verebilir.
- UK37. Bir isteğin bedeli giriş artı çıkış belirtecidir; başarısız çağrının girişi de sayılır, çünkü gönderilmiştir.
İstek Başına Defter
Toplam belirtecin tek bir sayı olarak raporlanması bir muhasebe değil bir toplamdır. Muhasebe, bedelin hangi isteğe ait olduğunu yazmayı gerektirir. Aşağıdaki defter her istek için bir satır tutar: kaç çağrı yapıldı, kaç belirteç girdi, kaç belirteç çıktı.
# BENZETICI -- KURGUDUR. Gercek bir model uc noktasi cagrilmaz; talepler, konusmalar # ve belgeler kurgudur, tohum 20260218. import math TOHUM, M32 = 20260218, 0xFFFFFFFF PENCERE, EN_UZUN = 240, 24 def uretec(t): x = ((t ^ (t >> 16)) * 2246822507) & M32 x = ((x ^ (x >> 13)) * 3266489909) & M32 s = [(x ^ (x >> 16)) & M32] def sonraki(): s[0] = (s[0] * 1664525 + 1013904223) & M32 return s[0] / 4294967296 return sonraki def ayrik(u, w): t = 0.0 for i, x in enumerate(w): t += x if u < t: return i return len(w) - 1 def belirtecle(m): # KURGU belirtecleyici, parca en cok bes damga b = [] for s in m.lower().replace(",", " , ").split(): while len(s) > 5: b.append(s[:5]) s = s[5:] b.append(s) return b def izno(m): h = 2166136261 for c in m: h = ((h ^ ord(c)) * 16777619) & M32 return h KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"] KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"] KALIP = {"fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi", "faturami odedim ama sistemde borc gorunuyor", "fatura ayrintisini nereden gorebilirim"], "ariza": ["evde su akmiyor bir ariza var galiba", "baglanti bozuk oldu ve hic calismiyor", "ariza kaydi actim ama ekip gelmedi"], "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor", "sayac degisimi icin randevu istiyorum", "sayac uzerindeki endeks ile fatura ayni degil"], "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum", "tarife degisikligi icin ne yapmam gerekiyor", "birim ucret abone tipine gore degisiyor mu"], "kesinti": ["mahallede kesinti var ne zaman gelecek", "planli kesinti duyurusu nereden takip edilir", "aksamdan beri kesinti yasiyoruz"]} IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura", "borc": "odeme", "odedi": "odeme", "ariza": "ariza", "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza", "sayac": "sayac", "endek": "sayac", "okuma": "sayac", "tarif": "tarife", "birim": "tarife", "abone": "tarife", "basam": "tarife", "kesin": "kesinti", "duyur": "kesinti", "mahal": "kesinti", "yardi": "bilgi", "nered": "bilgi", "kayit": "sikayet", "bekle": "sikayet"} SERBEST = ["talebiniz {k} konusunda kaydedildi ve ekibe iletildi", "{k} ile ilgili kaydiniz olusturuldu en kisa surede donulecek", "kaydiniz alindi ilgili birim sizinle iletisime gececek"] SAYAC = [0] def cagir(istem, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN): SAYAC[0] += 1 bel = belirtecle(istem) if len(bel) > PENCERE: return {"durum": "baglam_asimi", "giris": len(bel), "cikis": 0, "yanit": ""} if SAYAC[0] % 37 == 0: # hiz siniri cagri sayisina bagli return {"durum": "hiz_siniri", "giris": len(bel), "cikis": 0, "yanit": ""} r = uretec(tohum ^ izno(istem)) if len(bel) > 90 and r() < 0.04: return {"durum": "zaman_asimi", "giris": len(bel), "cikis": 0, "yanit": ""} aday = [k for k in KAVRAM if k[:5] in bel] # etiket kumesi adayi daraltir p = {k: 0.15 for k in (aday if len(aday) >= 3 else KAVRAM)} for t in bel: if IZ.get(t) in p: p[IZ[t]] += 1.0 if sicaklik <= 0.0: k = max(sorted(p), key=lambda a: p[a]) else: w = [math.exp(p[a] / sicaklik) for a in sorted(p)] k = sorted(p)[ayrik(r(), [x / sum(w) for x in w])] y = k if "tek" in bel else SERBEST[int(r() * 3)].format(k=k) cb = belirtecle(y) if len(cb) > en_uzun: # durdurma kosulu cb, y = cb[:en_uzun], " ".join(cb[:en_uzun]) return {"durum": "tamam", "giris": len(bel), "cikis": len(cb), "yanit": y} def oku(y): return next((s for s in y.split() if s in KONU), None) YONERGE = ("Talebi su etiketlerden birine ata: fatura , ariza , sayac , tarife , " "kesinti . Yanit olarak tek etiket yaz . Talep: ") BELGE = ["TR1 tarife basamaklari abone tipine gore belirlenir ve yilda bir guncellenir", "FT2 fatura itirazi kayit acildiktan sonra on is gunu icinde sonuclanir", "SY3 sayac degisimi randevusu saha ekibinin bolge programina baglidir", "AR4 ariza kaydi acilan adreste ekip ayni gun icinde yonlendirilir", "KS5 planli kesinti duyurulari bir hafta once ilan panosuna asilir"] KONUS, i = [], 0 while sum(len(c["tur"]) for c in KONUS) < 400: # KURGU is yuku: konusmalar r = uretec(TOHUM + 900 + i) i += 1 k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])] u = [1, 2, 3, 5, 8, 12][ayrik(r(), [0.46, 0.24, 0.14, 0.09, 0.05, 0.02])] KONUS.append({"no": i, "belge": ayrik(r(), [0.74, 0.16, 0.07, 0.03]), "tur": [{"konu": k, "metin": KALIP[k][(i + t) % 3]} for t in range(u)]}) ISTEK = [{"kon": c, "sira": t, "talep": c["tur"][t]} for c in KONUS for t in range(len(c["tur"]))][:400] def baglam(x, kip="tam"): t = x["kon"]["tur"][:x["sira"]] t = [] if kip == "durumsuz" else (t[-2:] if kip == "iki tur" else t) if kip == "ozet durum": g = "".join(f"Onceki konu: {o['konu']} . " for o in t) else: g = "".join(f"Onceki: {o['metin']} Yanit: {o['konu']} . " for o in t) return g + "".join(BELGE[(x["kon"]["no"] + j) % 5] + " . " for j in range(x["kon"]["belge"])) def defter(kip="tam", tohum=TOHUM): """Her istek icin ayri satir: cagri, giris belirteci, cikis belirteci.""" SAYAC[0] = 0 d = [] for x in ISTEK: c = g = ci = 0 ist = YONERGE + baglam(x, kip) + x["talep"]["metin"] for a in range(3): s = cagir(ist, tohum + a) # yeniden denemede tohum artar c, g, ci = c + 1, g + s["giris"], ci + s["cikis"] if s["durum"] == "tamam": break d.append({"top": g + ci, "cagri": c, "cikis": ci, "dogru": oku(s["yanit"]) == x["talep"]["konu"]}) return d k = defter() t = sorted(z["top"] for z in k) top = sum(t) print("konusma", len(KONUS), " istek", len(k), " cagri", sum(z["cagri"] for z in k), " toplam belirtec", top) print("ortalama %.1f ortanca %d yuzde 75 %d yuzde 90 %d yuzde 99 %d en buyuk %d" % (top / 400, t[200], t[300], t[360], t[396], t[-1])) for p, d in ((1, 4), (5, 20), (10, 40)): print("en pahali %%%-3d %5d belirtec, toplamin %.4f'i" % (p, sum(t[-d:]), sum(t[-d:]) / top)) k2 = defter(tohum=TOHUM + 1) t2 = sorted(z["top"] for z in k2) print("2. kosum ortalama %.1f ortanca %d en pahali %%1 payi %.4f" % (sum(t2) / 400, t2[200], sum(t2[-4:]) / sum(t2))) print("isabet %.4f / %.4f" % (sum(z["dogru"] for z in k) / 400, sum(z["dogru"] for z in k2) / 400))
konusma 154 istek 400 cagri 414 toplam belirtec 32642 ortalama 81.6 ortanca 69 yuzde 75 100 yuzde 90 139 yuzde 99 224 en buyuk 303 en pahali %1 975 belirtec, toplamin 0.0299'i en pahali %5 3892 belirtec, toplamin 0.1192'i en pahali %10 6932 belirtec, toplamin 0.2124'i 2. kosum ortalama 83.0 ortanca 69 en pahali %1 payi 0.0409 isabet 0.9125 / 0.8925
Ortalamanın Sakladığı Kuyruk
Tek sayıya indirilmiş bir rapor şunu söylerdi: dört yüz istek, otuz iki bin altı yüz kırk iki belirteç, istek başına 81,6. Bu sayıya bakan bir plan, istek sayısını iki katına çıkarmanın bedelini de iki katı olarak yazar ve yanılır.
Ortanca 69’dur, yani isteklerin yarısı ortalamanın altındadır. Ortalamayı yukarı çeken şey üst dilimlerdir: yüzde 75 dilimi 100, yüzde 90 dilimi 139, yüzde 99 dilimi 224 ve en pahalı istek 303 belirteç. En pahalı istek ortancanın dört katından fazlasıdır. Bu, bir bozukluk değildir; uzun konuşmaların kaçınılmaz sonucudur. Durum istemcide taşındığı için bir konuşmanın on ikinci isteği, o konuşmanın on bir turunu da yeniden gönderir.
Kuyruğun ağırlığı payla okunur. En pahalı yüzde bir, yani dört yüz isteğin dördü, toplamın 0,0299’unu harcıyor: kendi payının üç katı. En pahalı yüzde on ise 0,2124’ünü, yani payının iki katından fazlasını. Bir bütçe aşımı araştırmasında bakılacak yer bu kırk istektir; kalan üç yüz altmışın hepsini bir belirteç ucuzlatmak, aynı kazancı vermez.
Son iki satır ölçünün kendi kararlılığını sınıyor. İkinci koşumda ortalama 81,6’dan 83,0’a çıkıyor, yani binde on yedi oynuyor; ortanca 69’da sabit. Buna karşılık en pahalı yüzde birin payı 0,0299’dan 0,0409’a gidiyor, yani üçte birden fazla oynuyor. Kuyruk az sayıda isteğin üzerinde durduğu için gürültülüdür. Bunun doğrudan bir sonucu vardır: kuyruk payı tek bir koşumdan okunmaz, bir pencere boyunca biriktirilip okunur. Ortalamanın kararlı, kuyruğun oynak olması, ortalamaya güvenmek için değil, kuyruğu daha uzun ölçmek için bir gerekçedir.
Faturanın Kalemleri
Toplam belirtecin nereye gittiği, isteğin içindeki metin parçalarının ayrı ayrı sayılmasıyla bulunur. Aşağıdaki blok aynı defteri kalemlere ayırır ve ardından konuşma durumunu kısaltan üç politikayı aynı iş yükünde koşturur.
kalem = {"yonerge": 400 * len(belirtecle(YONERGE)), "konusma durumu": sum(len(belirtecle(baglam(x))) - len(belirtecle(baglam(x, "durumsuz"))) for x in ISTEK), "belge": sum(len(belirtecle(baglam(x, "durumsuz"))) for x in ISTEK), "talep metni": sum(len(belirtecle(x["talep"]["metin"])) for x in ISTEK), "cikis": sum(z["cikis"] for z in k)} kalem["yeniden deneme"] = top - sum(kalem.values()) print("kalem belirtec pay") for a, v in kalem.items(): print(f"{a:<16} {v:>8} {v / top:>7.4f}") print("\npolitika toplam istek basi yuzde 99 en pahali %1 isabet dogru basi") for kip in ("tam", "iki tur", "ozet durum", "durumsuz"): d = defter(kip) s = sorted(z["top"] for z in d) tt, dg = sum(s), sum(z["dogru"] for z in d) print(f"{kip:<12} {tt:>7} {tt / 400:>11.1f} {s[396]:>9} {sum(s[-4:]) / tt:>13.4f}" f" {dg / 400:>7.4f} {tt / dg:>11.1f}")
kalem belirtec pay yonerge 12800 0.3921 konusma durumu 11939 0.3658 belge 2344 0.0718 talep metni 3885 0.1190 cikis 625 0.0191 yeniden deneme 1049 0.0321 politika toplam istek basi yuzde 99 en pahali %1 isabet dogru basi tam 32642 81.6 224 0.0299 0.9125 89.4 iki tur 27401 68.5 198 0.0314 0.9125 75.1 ozet durum 24355 60.9 120 0.0259 0.9075 67.1 durumsuz 20198 50.5 95 0.0276 0.7975 63.3
Kalem tablosunun ilk okuması şudur: bu faturanın yalnız 0,1190’ı yeni bilgi taşıyor. Talep metni, yani abonenin o istekte yazdığı cümle, üç bin sekiz yüz seksen beş belirteçtir. Geri kalanın en büyük iki kalemi yinelenen metindir — yönerge 0,3921, konuşma durumu 0,3658 — ve ikisi birlikte toplamın dörtte üçüne yakınını tutar. Çıkış belirteci ise 0,0191, yani ihmal edilebilir; bu düzenekte model tek bir etiket yazıyor ve yazdığı şeyin bedeli, okuduğu şeyin bedelinin yanında görünmüyor.
Bu ayrım, hangi düzeneğin nereye dokunduğunu da söylüyor. Yönerge kalemi her istekte birebir aynıdır ve önbelleklemenin hedefi odur; konuşma durumu kalemi istekten isteğe büyür ve kısaltmanın hedefi odur. İkisi ayrı sayılmadan hangi düzeneğin ne kazandıracağı bilinemez.
Hangi Birimle Bakıldığı
Politika tablosu dört kurulumu aynı iş yükünde karşılaştırıyor. İstek başına sütununa bakan bir okuma nettir: durumu tamamen atmak 81,6’yı 50,5’e indiriyor, yani üçte birden fazla kazandırıyor. Aynı satırın isabeti 0,7975’tir; tam durumun 0,9125’ine göre 0,1150 düşük. İki koşum farkı 0,0200 olduğuna göre bu düşüş gerçektir ve dört yüz istekte kırk altı yanlış etiket demektir.
Son sütun aynı dört satırı doğru yanıt başına okuyor ve sıralamayı bozuyor: 89,4 / 75,1 / 67,1 / 63,3. Durumsuz kurulum, isabeti en düşük olduğu hâlde doğru yanıt başına en ucuz olanıdır. İki birim iki farklı kazananı gösteriyor, çünkü ilki yanlış yanıtın bedelini sıfır sayıyor. Bir destek hattında yanlış etiket bedelsiz değildir; yanlış yönlendirilmiş kırk altı talep, elle düzeltme işi doğurur. Hangi birimin doğru olduğu ölçümün değil ürünün kararıdır, ama hangi birimle bakıldığının yazılması ölçümün sorumluluğudur.
Üçüncü satır ise ölçülemeyen bir kazançtır. Özet durum kurulumu isabeti 0,9125’ten 0,9075’e indiriyor; fark 0,0050, iki koşum farkının dörtte biri. Bu satır “isabeti düşürmüyor” diye okunabilir, ama doğrusu “düşürüp düşürmediği bu ölçümle bilinemez” olmalıdır. Karşılığında kazandırdığı 8287 belirteç ise ölçülmüştür.
Kuyruk sütunu ayrıca ters bir davranış gösteriyor. İki tur kurulumu toplamı 32642’den 27401’e indirdiği hâlde en pahalı yüzde birin payı 0,0299’dan 0,0314’e çıkıyor. Kısaltma toplamı, kuyruğu kestiğinden daha çok kestiği için pay büyüyor. Kuyruk payı bir oran olduğundan tek başına okunamaz; yanında toplam yazmalıdır.
Özet
- Maliyetin birimi belirteçtir; para birimi yazılmaz, çünkü fiyat sağlayıcıya bağlıdır, belirteç sayısı düzeneğin kendi ürettiği bir sayıdır.
- Ortalama 81,6, ortanca 69, yüzde 99 dilimi 224 ve en büyük istek 303 belirteçtir; ortalamaya bakan bir plan uzun konuşmaların bedelini göremez.
- En pahalı yüzde bir toplamın 0,0299’unu, en pahalı yüzde on 0,2124’ünü harcıyor: bütçe araştırması kırk isteğe bakarak yapılır.
- Ortalama iki koşumda 81,6’dan 83,0’a oynarken kuyruk payı 0,0299’dan 0,0409’a gidiyor; kuyruk tek koşumdan değil bir pencereden okunur.
- Faturanın 0,3921’i yönerge, 0,3658’i konuşma durumu, yalnız 0,1190’ı yeni bilgi taşıyan talep metnidir; çıkış belirteci 0,0191’dir.
- Aynı dört politika istek başına ve doğru yanıt başına okunduğunda farklı sıralanır (50,5’e karşı 63,3); hangi birimle bakıldığı yazılmadan sıralama okunamaz.
Sonraki Adım
Bu dersin defteri her isteği aynı sayıyor: bir istek gitti, bir yanıt geldi, şu kadar belirteç tutuldu. Defterin göremediği bir sütun var. Dört yüz isteğin bir bölümü, uç nokta yanıt vermediği için başka bir yoldan geçtiğinde de aynı satırı yazacaktır: çağrı sayısı, belirteç, hatta bir etiket. Yanıtın nereden geldiği deftere yazılmıyor. Sonraki ders kesinti karşısında ikinci bir yola düşen isteklerin payını sayar ve o isteklerin isabetini ayrı basar: kesinti kapatıldığında kullanıcıya görünen hata sıfıra iner, toplam isabet neredeyse hiç oynamaz ve düşüş yalnız yanıtın kaynağı deftere yazıldığında görünür.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.