Değişkenleri bir döngünün arkasında mı yoksa bir döngünün içinde mi bildiriyorsunuz? - sayfa 2

 
Georgiy Merts :

Numara. Şaka yapmıyorum.

Tabii ki, bu durumda, normal bir derleyici, döngü içindeki bir değişkenin bildirimini çıkarmalıdır.

Ben sadece "derleyici için umut et, ama kendin hata yapma" diye düşünüyorum. Derleyici standardı, bildirim sırasında yerel bir değişkenin oluşturulduğunu ve bildirildiği blok çıktığında silindiğini varsayar. Bu nedenle, bu ilke ilk etapta yönlendirilmeli ve derleyicinin kodunuzu sizin için geliştirmesini beklememelidir.

Öyleyse diyorum ki, "hata yapmamak" istiyorsanız, o zaman montajcıya gidin. Her şeyi kişisel olarak kontrol etmeniz gerektiğinden ... Sonuçta, açıklanan durum tam bir önemsememek. Daha karmaşık büyüklük sıraları olan şeyler var. OOP sizin için kesinlikle kontrendikedir. Derleyicinin şu veya bu sanal yöntemi normal bir çağrıya dönüştürdüğünü veya gereksiz bir işaretçi kontrolünü kesip kesmediğini bilemezsiniz ... Böyle bir paranoya ile yönetilen MQL'de ne yapılabilir? )

Ve kodu derleyicinin (ve hayali olanların) özelliklerine göre, kodun doğruluğuna ve güvenilirliğine zarar verecek şekilde ayarlamak - bu açıkça iyi bir programcının yapması gereken şey değildir. Ve burada kodun yanlışlığından bahsediyoruz. Değişken, kullanıldığı blokta doğrudan bildirilmelidir.

 
Vict :

Kahretsin, bu sadece vahşi yoğunluk, yorumlanacak ne var, hata ayıklayıcının tamamen yanlış anlaşılması.

- evet.
 
Alexey Navoykov :
- evet.

Anaokulunda olduğu gibi)) Tankta olanlar için açıklıyorum: önce g++ 1.cpp'yi derliyoruz, kesme noktaları yok, derleyici onlar hakkında hiçbir şey bilmiyor. Sonra hata ayıklayıcıyı başlatıyoruz: gdb a.out ve ancak şimdi bir kesme noktası ayarladık.

Ne saçma sapan söylediklerini anlıyor musun?

 
Alexey Navoykov :

Optimizasyon yalnızca derlenmiş kodla veya performans ölçülerek tespit edilebilir. Bu yüzden yapılacak ilk şey bu. Ve sakin ol)

2019.08.18 10:28:12.826 Hız Testi (EURUSD,H1) 1. s1=rand(): döngüler=100000000 ms=7031

2019.08.18 10:28:19.885 Hız Testi (EURUSD,H1) 2. s2=rand(): döngüler=100000000 ms=7063

2019.08.18 10:28:27.037 Hız Testi (EURUSD,H1) 3. s3=rand(): döngüler=100000000 ms=7140

2019.08.18 10:28:34.045 Hız Testi (EURUSD,H1) 4. s4=rand(): döngüler=100000000 ms=7016

2019.08.18 10:28:41.135 Hız Testi (EURUSD,H1) 5. s5=rand(): döngüler=100000000 ms=7094

2019.08.18 10:28:47.896 Hız Testi (EURUSD,H1) 1. q=rand(): döngüler=100000000 ms=6750

2019.08.18 10:28:54.659 Hız Testi (EURUSD,H1) 2. q=rand(): döngüler=100000000 ms=6765

2019.08.18 10:29:01.47 Hız Testi (EURUSD,H1) 3. q=rand(): döngüler=100000000 ms=6797

2019.08.18 10:29:08.257 Hız Testi (EURUSD,H1) 4. q=rand(): döngüler=100000000 ms=6797

2019.08.18 10:29:15.102 Hız Testi (EURUSD,H1) 5. q=rand(): döngüler=100000000 ms=6844

 //+------------------------------------------------------------------+
//|                                                    SpeedTest.mq5 |
//|                                                            IgorM |
//|                              https://www.mql5.com/ru/users/igorm |
//+------------------------------------------------------------------+
#property copyright "IgorM"
#property link        "https://www.mql5.com/ru/users/igorm"
#property version    "1.00"
#define N 8

#define   test(M,S,EX) { uint mss= GetTickCount (); ulong nn=( ulong ) pow ( 10 ,M); for ( ulong tst= 0 ;tst<nn&&! _StopFlag ;tst++){EX;} \
                         printf ( "%s: loops=%i ms=%u" ,S,nn, GetTickCount ()-mss);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart ()
  {
   string s1; srand ( GetTickCount ()); test(N, "1. s1=rand()" ,s1= IntegerToString ( rand ()));
   string s2; srand ( GetTickCount ()); test(N, "2. s2=rand()" ,s2= IntegerToString ( rand ()));
   string s3; srand ( GetTickCount ()); test(N, "3. s3=rand()" ,s3= IntegerToString ( rand ()));
   string s4; srand ( GetTickCount ()); test(N, "4. s4=rand()" ,s4= IntegerToString ( rand ()));
   string s5; srand ( GetTickCount ()); test(N, "5. s5=rand()" ,s5= IntegerToString ( rand ()));

   srand ( GetTickCount ()); test(N, "1. q=rand()" , string q= IntegerToString ( rand ()));
   srand ( GetTickCount ()); test(N, "2. q=rand()" , string q= IntegerToString ( rand ()));
   srand ( GetTickCount ()); test(N, "3. q=rand()" , string q= IntegerToString ( rand ()));
   srand ( GetTickCount ()); test(N, "4. q=rand()" , string q= IntegerToString ( rand ()));
   srand ( GetTickCount ()); test(N, "5. q=rand()" , string q= IntegerToString ( rand ()));
  }
//+------------------------------------------------------------------+
 
Hata ayıklayıcının altına benzer bir kod kazdım, ancak kullanıcı operatörü yeni olmadan, bazı şüpheler olabilir - kullanıcı operatörünün optimize edilmediğini söylüyorlar. libc'den malloc()'a yapılan çağrıları yakalamak. Sonuç: döngüdeki bir dize - her baskıdan önce, döngünün dışında malloc'a yapılan bir çağrı - bir grup baskıdan önce bir çağrı. Artık herhangi bir şüphe olamaz, sadece ilk seçeneği kullanmak daha iyidir. Tabii ki, mikrolitrede başka bir şey mümkündür, ancak yetişkin dillerine odaklanmak daha iyidir.
 
#define N 9

2019.08.18 10:37:59.620 Hız Testi (EURUSD,H1) 1. s1=rand(): döngüler=1000000000 ms=70672

2019.08.18 10:39:10.352 Hız Testi (EURUSD,H1) 2. s2=rand(): döngüler=1000000000 ms=70719

2019.08.18 10:40:21.908 Hız Testi (EURUSD,H1) 3. s3=rand(): döngüler=1000000000 ms=71562

2019.08.18 10:41:32.315 Hız Testi (EURUSD,H1) 4. s4=rand(): döngüler=1000000000 ms=70407

2019.08.18 10:42:42.996 Hız Testi (EURUSD,H1) 5. s5=rand(): döngüler=1000000000 ms=70687

2019.08.18 10:43:50.964 Hız Testi (EURUSD,H1) 1. q=rand(): döngüler=1000000000 ms=67969

2019.08.18 10:44:58.887 Hız Testi (EURUSD,H1) 2. q=rand(): döngüler=1000000000 ms=67922

2019.08.18 10:46:06.829 Hız Testi (EURUSD,H1) 3. q=rand(): döngüler=1000000000 ms=67937

2019.08.18 10:47:14.602 Hız Testi (EURUSD,H1) 4. q=rand(): döngüler=1000000000 ms=67766

2019.08.18 10:48:22.428 Hız Testi (EURUSD,H1) 5. q=rand(): döngüler=1000000000 ms=67828

 

Igor Makanu:

 #define   test(M,S,EX) { uint mss= GetTickCount (); ulong nn=( ulong ) pow ( 10 ,M); for ( ulong tst= 0 ;tst<nn&&! _StopFlag ;tst++){EX;} \

Kahretsin, boşluk çubuğun chtol çalışmıyor mu? ) İlk defa fark etmiyorum. Veya sabit sürücünüzde bayt tasarrufu mu yapıyorsunuz? )

 
Alexey Navoykov :

Benimle dalga mı geçiyorsun? Bu derleyici için o kadar önemsiz bir durum ki burada söylenecek bir şey bile yok. Ve böyle bir paranoya ile, tamamen montajcıda kodlayabilirsiniz) Bu bile şu anda zaten anlamsız hale geliyor. Modern derleyicilerin optimizasyonlarını aşmak için çok denemeniz gerekir.

ps Belki de bu vakadaki önemsizlik konusunda biraz heyecanlandım, çünkü bir dizge tamponundan bahsediyoruz. Ancak MQL'de saklanması garanti edilir. Ve yalnızca döngü içinde değil, işlev çağrıları arasında bile. Bu konu burada defalarca tartışıldı.

Bu ifadenin yazarının işlemcinin, belleğin ve derleyicinin nasıl çalıştığından tamamen habersiz olduğuna dair bir şüphem var... Kodunuzun herhangi birinin en az onlarca, hatta yüzlerce kez hızlandırılabileceğine bahse girerim. Böyle boktan kodlayıcılar yüzünden, çoğu ürün artık düzinelerce çekirdeğe sahip en güçlü bilgisayarlarda utanmadan yavaşlıyor, ama sadece biraz düşünmeniz gerekiyor... Ama bazı insanlar şöyle düşünüyor - "Neden düşünüyorsunuz? Kodlamanız gerekiyor..."

Bilginize, şu anda hiçbir derleyici programcının sonuç olarak ne elde etmek istediğini anlamayı öğrenmedi. Bazı döngüleri açabilir, bazı bellek erişimlerini optimize edebilir, böylece veriler işlemci önbelleğinde olur, ancak kod başlangıçta optimize edilmemiş ve tek bir yerden yazılmamışsa, o zaman hiçbir derleyici size yardımcı olmaz ...

Not Boş zamanlarınızda Chris Kaspersky'nin eğlenceli küçük kitabını okuyun " Programları optimize etme tekniği. Belleğin verimli kullanımı"

 
Alexey Volchanskiy :

George haklı, garanti değil.

Ve 'sayı'dan 'dize' uyarısına örtülü dönüşümü alıyoruz


Ve belirsizlikten ve uyarıdan tam olarak bu şekilde kurtuluruz.

 for ( int i = 0 ; i < 1000 ; i++)
   {
       static string st = IntegerToString (i);
      ...
   }

Ve ben her zaman yaptım

 string st = ( string )i;

Ve neden statik? atama yalnızca bir kez ilk yinelemede çalışacak


Yürütme hızını ölçmeye karar verdi

   CStopWatch sw; // Секундомер, для замера времени
   
   sw.Start();
   for ( int i = 0 ; i < 10000000 ; i++)
   {
       string st = ( string )i;
   }
   pr( "Test1, время выполнения: " + sw.Stop());

   sw.Start();
   string st = "" ;
   for ( int i = 0 ; i < 10000000 ; i++)
   {
      st = ( string )i;
   }
   pr( "Test2, Время выполнения: " + sw.Stop());

Sonuç:

Test1, время выполнения: 0.548275 сек.
Test2, Время выполнения: 0.313978 сек.

Birçok kez başlatıldı, sonuç kararlı, döngünün arkasındaki değişkenin bildirimi ile kod daha hızlı çalışıyor

 
Alexey Navoykov :

Kahretsin, boşluk çubuğun chtol çalışmıyor mu? ) İlk defa fark etmiyorum. Veya sabit sürücünüzde bayt tasarrufu mu yapıyorsunuz? )

hayır bu kod benim değil, biraz taradım - kodu "ondalık basamak sayısını arama" konusundan kendime kopyaladım ve tartışmalı konularda kullanıyorum, düzenlemeye çok tembelim,

genel olarak boşluklarım var ve tembelliğim var))))

Not: Örnek bir kod verin kendim için kopyalayayım ilerde istediğiniz gibi olur prensipte bu beni rahatsız etmez

not: burada:

 #define   test(M,S,EX) {                                 \
uint mss= GetTickCount ();                                 \
ulong nn=( ulong ) pow ( 10 ,M);                               \
for ( ulong tst= 0 ;tst<nn && ! _StopFlag ;tst++) \
{ EX; }                                                  \
printf ( "%s: loops=%i ms=%u" ,S,nn, GetTickCount ()-mss);}
Neden: